blob: 75ae6d1af44bc0086e848251889ddaa01225276d [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2018-2020 Oplus. All rights reserved.
*/
#include <linux/delay.h>
#include <linux/power_supply.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <linux/of_gpio.h>
#include <linux/kthread.h>
#include <linux/version.h>
#include <linux/reboot.h>
#include <linux/module.h>
#include <linux/sched/clock.h>
#include <soc/oplus/system/oplus_project.h>
#ifdef CONFIG_OPLUS_CHARGER_MTK
//#include <mtk_boot_common.h>
#include <mt-plat/mtk_boot.h>
#include <linux/gpio.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0))
#include <uapi/linux/sched/types.h>
#endif
#else /* CONFIG_OPLUS_CHARGER_MTK */
#include <linux/spinlock.h>
#include <linux/gpio.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/of.h>
#include <linux/bitops.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
#include <linux/spmi.h>
#include <linux/printk.h>
#include <linux/ratelimit.h>
#include <linux/debugfs.h>
#include <linux/leds.h>
#include <linux/rtc.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
#include <linux/qpnp/qpnp-adc.h>
#else
#include <uapi/linux/sched/types.h>
#endif
#include <linux/batterydata-lib.h>
#include <linux/of_batterydata.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0))
#include <linux/msm_bcl.h>
#endif
#include <linux/ktime.h>
#include <linux/kernel.h>
#endif
#include "oplus_charger.h"
#include "oplus_gauge.h"
#include "oplus_vooc.h"
#include "oplus_short.h"
#include "oplus_adapter.h"
#include "charger_ic/oplus_short_ic.h"
#include "oplus_debug_info.h"
#ifndef CONFIG_OPLUS_CHARGER_MTK
#ifndef WPC_NEW_INTERFACE
#include "oplus_wireless.h"
#include "wireless_ic/oplus_chargepump.h" //for WPC
#else
#include "oplus_wireless.h"
#endif
#endif
static struct oplus_chg_chip *g_charger_chip = NULL;
#define MAX_UI_DECIMAL_TIME 24
#define UPDATE_TIME 1
#define OPLUS_CHG_UPDATE_INTERVAL_SEC 5
/* first run after init 10s */
#define OPLUS_CHG_UPDATE_INIT_DELAY round_jiffies_relative(msecs_to_jiffies(500))
/* update cycle 5s */
#define OPLUS_CHG_UPDATE_INTERVAL round_jiffies_relative(msecs_to_jiffies(OPLUS_CHG_UPDATE_INTERVAL_SEC*1000))
#define OPLUS_CHG_DEFAULT_CHARGING_CURRENT 512
int enable_charger_log = 0;
int charger_abnormal_log = 0;
int tbatt_pwroff_enable = 1;
extern bool oplus_is_power_off_charging(struct oplus_vooc_chip *chip);
bool check_fastchg_quit = false;
/* wenbin.liu@SW.Bsp.Driver, 2016/03/01 Add for log tag*/
#define charger_xlog_printk(num, fmt, ...) \
do { \
if (enable_charger_log >= (int)num) { \
printk(KERN_NOTICE pr_fmt("[OPLUS_CHG][%s]"fmt), __func__, ##__VA_ARGS__); \
} \
} while (0)
void oplus_chg_turn_off_charging(struct oplus_chg_chip *chip);
void oplus_chg_turn_on_charging(struct oplus_chg_chip *chip);
static void oplus_chg_smooth_to_soc(struct oplus_chg_chip *chip);
static void oplus_chg_variables_init(struct oplus_chg_chip *chip);
static void oplus_chg_update_work(struct work_struct *work);
static void oplus_chg_reset_adapter_work(struct work_struct *work);
static void oppo_fastchg_check_work(struct work_struct *work);
static void oplus_chg_protection_check(struct oplus_chg_chip *chip);
static void oplus_chg_get_battery_data(struct oplus_chg_chip *chip);
static void oplus_chg_check_tbatt_status(struct oplus_chg_chip *chip);
static void oplus_chg_check_tbatt_normal_status(struct oplus_chg_chip *chip);
static void oplus_chg_get_chargerid_voltage(struct oplus_chg_chip *chip);
void oplus_chg_set_input_current_limit(struct oplus_chg_chip *chip);
static void oplus_chg_set_charging_current(struct oplus_chg_chip *chip);
static void oplus_chg_battery_update_status(struct oplus_chg_chip *chip);
static void oplus_chg_pdqc_to_normal(struct oplus_chg_chip *chip);
static void oplus_get_smooth_soc_switch(struct oplus_chg_chip *chip);
static void oplus_chg_pd_config(struct oplus_chg_chip *chip);
static void oplus_chg_qc_config(struct oplus_chg_chip *chip);
#ifdef CONFIG_FB
static int fb_notifier_callback(struct notifier_block *nb, unsigned long event, void *data);
#endif
void oplus_chg_ui_soc_decimal_init(void);
void oplus_chg_ui_soc_decimal_deinit(void);
static void oplus_chg_show_ui_soc_decimal(struct work_struct *work);
static int chgr_dbg_vchg = 0;
module_param(chgr_dbg_vchg, int, 0644);
MODULE_PARM_DESC(chgr_dbg_vchg, "debug charger voltage");
static int chgr_dbg_total_time = 0;
module_param(chgr_dbg_total_time, int, 0644);
MODULE_PARM_DESC(chgr_dbg_total_time, "debug charger total time");
/****************************************/
static int reset_mcu_delay = 0;
static bool suspend_charger = false;
static bool vbatt_higherthan_4180mv = false;
static bool vbatt_lowerthan_3300mv = false;
enum power_supply_property oplus_usb_props[] = {
POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_OTG_SWITCH,
POWER_SUPPLY_PROP_OTG_ONLINE,
};
enum power_supply_property oplus_ac_props[] = {
POWER_SUPPLY_PROP_ONLINE,
#ifdef CONFIG_OPLUS_FAST2NORMAL_CHG
POWER_SUPPLY_PROP_FAST2NORMAL_CHG,
#endif
};
enum power_supply_property oplus_batt_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_MIN,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_AUTHENTICATE,
POWER_SUPPLY_PROP_CHARGE_TIMEOUT,
POWER_SUPPLY_PROP_CHARGE_TECHNOLOGY,
POWER_SUPPLY_PROP_FAST_CHARGE,
POWER_SUPPLY_PROP_MMI_CHARGING_ENABLE, /*add for MMI_CHG_TEST*/
#ifdef CONFIG_OPLUS_CHARGER_MTK
POWER_SUPPLY_PROP_STOP_CHARGING_ENABLE,
POWER_SUPPLY_PROP_CHARGE_COUNTER,
POWER_SUPPLY_PROP_CURRENT_MAX,
#endif
#ifndef CONFIG_OPLUS_SDM670_CHARGER
POWER_SUPPLY_PROP_CHARGE_FULL,
#endif
POWER_SUPPLY_PROP_BATTERY_FCC,
POWER_SUPPLY_PROP_BATTERY_SOH,
POWER_SUPPLY_PROP_BATTERY_CC,
POWER_SUPPLY_PROP_BATTERY_RM,
POWER_SUPPLY_PROP_BATTERY_NOTIFY_CODE,
#ifdef CONFIG_OPLUS_SMART_CHARGER_SUPPORT
POWER_SUPPLY_PROP_COOL_DOWN,
#endif
POWER_SUPPLY_PROP_ADAPTER_FW_UPDATE,
POWER_SUPPLY_PROP_VOOCCHG_ING,
#ifdef CONFIG_OPLUS_CHECK_CHARGERID_VOLT
POWER_SUPPLY_PROP_CHARGERID_VOLT,
#endif
#ifdef CONFIG_OPLUS_SHIP_MODE_SUPPORT
POWER_SUPPLY_PROP_SHIP_MODE,
#endif
#ifdef CONFIG_OPLUS_CALL_MODE_SUPPORT
POWER_SUPPLY_PROP_CALL_MODE,
#endif
#ifdef CONFIG_OPLUS_SHORT_C_BATT_CHECK
#ifdef CONFIG_OPLUS_SHORT_USERSPACE
POWER_SUPPLY_PROP_SHORT_C_LIMIT_CHG,
POWER_SUPPLY_PROP_SHORT_C_LIMIT_RECHG,
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
#else
POWER_SUPPLY_PROP_SHORT_C_BATT_UPDATE_CHANGE,
POWER_SUPPLY_PROP_SHORT_C_BATT_IN_IDLE,
POWER_SUPPLY_PROP_SHORT_C_BATT_CV_STATUS,
#endif /*CONFIG_OPLUS_SHORT_USERSPACE*/
#endif
#ifdef CONFIG_OPLUS_SHORT_HW_CHECK
POWER_SUPPLY_PROP_SHORT_C_HW_FEATURE,
POWER_SUPPLY_PROP_SHORT_C_HW_STATUS,
#endif
#ifdef CONFIG_OPLUS_SHORT_IC_CHECK
POWER_SUPPLY_PROP_SHORT_C_IC_OTP_STATUS,
POWER_SUPPLY_PROP_SHORT_C_IC_VOLT_THRESH,
POWER_SUPPLY_PROP_SHORT_C_IC_OTP_VALUE,
#endif
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
};
#ifdef CONFIG_OPLUS_CHARGER_MTK
int oplus_usb_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
int ret = 0;
//struct oplus_chg_chip *chip = container_of(psy->desc, struct oplus_chg_chip, usb_psd);
struct oplus_chg_chip *chip = g_charger_chip;
if (chip->charger_exist) {
if ((chip->charger_type == POWER_SUPPLY_TYPE_USB
|| chip->charger_type == POWER_SUPPLY_TYPE_USB_CDP)
&& chip->stop_chg == 1) {
chip->usb_online = true;
chip->usb_psd.type = POWER_SUPPLY_TYPE_USB;
}
} else {
chip->usb_online = false;
}
switch (psp) {
case POWER_SUPPLY_PROP_CURRENT_MAX:
val->intval = 500000;
break;
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
val->intval = 5000000;
break;
case POWER_SUPPLY_PROP_ONLINE:
val->intval = chip->usb_online;
break;
case POWER_SUPPLY_PROP_OTG_SWITCH:
val->intval = chip->otg_switch;
break;
case POWER_SUPPLY_PROP_OTG_ONLINE:
val->intval = chip->otg_online;
break;
default:
pr_err("get prop %d is not supported in usb\n", psp);
ret = -EINVAL;
break;
}
return ret;
}
int oplus_usb_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
int ret = 0;
switch (psp) {
case POWER_SUPPLY_PROP_OTG_SWITCH:
return 1;
default:
pr_err("writeable prop %d is not supported in usb\n", psp);
ret = -EINVAL;
break;
}
return 0;
}
void __attribute__((weak)) oplus_set_otg_switch_status(bool value)
{
return;
}
int oplus_usb_set_property(struct power_supply *psy,
enum power_supply_property psp,
const union power_supply_propval *val)
{
int ret = 0;
//struct oplus_chg_chip *chip = container_of(psy->desc, struct oplus_chg_chip, usb_psd);
struct oplus_chg_chip *chip = g_charger_chip;
switch (psp) {
case POWER_SUPPLY_PROP_OTG_SWITCH:
if (val->intval == 1) {
chip->otg_switch = true;
oplus_set_otg_switch_status(true);
} else {
chip->otg_switch = false;
chip->otg_online = false;
oplus_set_otg_switch_status(false);
}
charger_xlog_printk(CHG_LOG_CRTI, "otg_switch: %d\n", chip->otg_switch);
break;
default:
pr_err("set prop %d is not supported in usb\n", psp);
ret = -EINVAL;
break;
}
return ret;
}
static void usb_update(struct oplus_chg_chip *chip)
{
if (chip->charger_exist) {
/*if (chip->charger_type==STANDARD_HOST || chip->charger_type==CHARGING_HOST) {*/
if (chip->charger_type == POWER_SUPPLY_TYPE_USB
|| chip->charger_type == POWER_SUPPLY_TYPE_USB_CDP) {
chip->usb_online = true;
chip->usb_psd.type = POWER_SUPPLY_TYPE_USB;
}
} else {
chip->usb_online = false;
}
power_supply_changed(chip->usb_psy);
}
#endif
static void fastchgquit_check(void)
{
struct oplus_chg_chip *chip = g_charger_chip;
if (!chip) {
chg_err("g_oppo_chip is NULL\n");
return;
}
if((!chip->charger_exist) && chip->ac_online && (chip->chg_ops->get_charger_volt() < 2500) && check_fastchg_quit){
chg_err("charger_exist null, turn off fastchg\n");
//if(get_reset_gpio_value()) {
chg_err("pull down mcu_en\n");
oplus_vooc_turn_off_fastchg();
//}
}
check_fastchg_quit = false;
}
int oplus_ac_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
int ret = 0;
//struct oplus_chg_chip *chip = container_of(psy->desc, struct oplus_chg_chip, ac_psd);
struct oplus_chg_chip *chip = g_charger_chip;
if (chip->charger_exist) {
if ((chip->charger_type == POWER_SUPPLY_TYPE_USB_DCP || suspend_charger)
|| (oplus_vooc_get_fastchg_started() == true)
|| (oplus_vooc_get_fastchg_to_normal() == true)
|| (oplus_vooc_get_fastchg_to_warm() == true)
|| (oplus_vooc_get_fastchg_dummy_started() == true)
|| (oplus_vooc_get_adapter_update_status() == ADAPTER_FW_NEED_UPDATE)
|| (oplus_vooc_get_btb_temp_over() == true)) {
chip->ac_online = true;
} else {
chip->ac_online = false;
}
} else {
if ((oplus_vooc_get_fastchg_started() == true)
|| (oplus_vooc_get_fastchg_to_normal() == true)
|| (oplus_vooc_get_fastchg_to_warm() == true)
|| (oplus_vooc_get_fastchg_dummy_started() == true)
|| (oplus_vooc_get_adapter_update_status() == ADAPTER_FW_NEED_UPDATE)
|| (oplus_vooc_get_btb_temp_over() == true)
|| chip->mmi_fastchg == 0) {
chip->ac_online = true;
} else {
chip->ac_online = false;
}
}
switch (psp) {
case POWER_SUPPLY_PROP_ONLINE:
val->intval = chip->ac_online;
break;
#ifdef CONFIG_OPLUS_FAST2NORMAL_CHG
case POWER_SUPPLY_PROP_FAST2NORMAL_CHG:
if (oplus_vooc_get_fastchg_to_normal() == true
|| oplus_vooc_get_fastchg_to_warm() == true
|| oplus_vooc_get_btb_temp_over() == true
|| oplus_vooc_get_fastchg_low_temp_full() == true) {
val->intval = 1;
} else {
val->intval = 0;
}
break;
#endif
default:
pr_err("get prop %d is not supported in ac\n", psp);
ret = -EINVAL;
break;
}
if (chip->ac_online) {
charger_xlog_printk(CHG_LOG_CRTI, "chg_exist:%d, ac_online:%d\n",
chip->charger_exist, chip->ac_online);
}
if((!chip->charger_exist) && chip->ac_online ){
if (!check_fastchg_quit){
check_fastchg_quit = true;
schedule_delayed_work(&chip->fastcheck_work, OPLUS_CHG_UPDATE_INTERVAL);
} else {
check_fastchg_quit = false;
}
}
return ret;
}
int oplus_battery_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
int rc = 0;
switch (psp) {
case POWER_SUPPLY_PROP_MMI_CHARGING_ENABLE:
rc = 1;
break;
#ifdef CONFIG_OPLUS_SMOOTH_SOC
case POWER_SUPPLY_PROP_SMOOTH_SWITCH:
rc = 1;
break;
#endif
#ifdef CONFIG_OPLUS_SMART_CHARGER_SUPPORT
case POWER_SUPPLY_PROP_COOL_DOWN:
rc = 1;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
if (g_charger_chip && g_charger_chip->smart_charging_screenoff) {
rc = 1;
} else {
rc = 0;
}
break;
#endif
#ifdef CONFIG_OPLUS_CHARGER_MTK
case POWER_SUPPLY_PROP_STOP_CHARGING_ENABLE:
rc = 1;
break;
#endif
#ifdef CONFIG_OPLUS_SHIP_MODE_SUPPORT
case POWER_SUPPLY_PROP_SHIP_MODE:
rc = 1;
break;
#endif
#ifdef CONFIG_OPLUS_CALL_MODE_SUPPORT
case POWER_SUPPLY_PROP_CALL_MODE:
rc = 1;
break;
#endif
#ifdef CONFIG_OPLUS_SHORT_C_BATT_CHECK
#ifdef CONFIG_OPLUS_SHORT_USERSPACE
case POWER_SUPPLY_PROP_SHORT_C_LIMIT_CHG:
case POWER_SUPPLY_PROP_SHORT_C_LIMIT_RECHG:
#else
case POWER_SUPPLY_PROP_SHORT_C_BATT_UPDATE_CHANGE:
case POWER_SUPPLY_PROP_SHORT_C_BATT_IN_IDLE:
#endif /*CONFIG_OPLUS_SHORT_USERSPACE*/
rc = 1;
break;
#endif
#ifdef CONFIG_OPLUS_SHORT_HW_CHECK
case POWER_SUPPLY_PROP_SHORT_C_HW_FEATURE:
rc = 1;
break;
#endif
#ifdef CONFIG_OPLUS_SHORT_IC_CHECK
case POWER_SUPPLY_PROP_SHORT_C_IC_VOLT_THRESH:
rc = 1;
break;
#endif
#ifdef CONFIG_OPLUS_CHIP_SOC_NODE
case POWER_SUPPLY_PROP_CHIP_SOC:
rc = 1;
break;
#endif
// pr_err("writeable prop %d is not supported in batt\n", psp);
default:
rc = 0;
break;
}
return rc;
}
int oplus_battery_set_property(struct power_supply *psy,
enum power_supply_property psp,
const union power_supply_propval *val)
{
int ret = 0;
//struct oplus_chg_chip *chip = container_of(psy->desc, struct oplus_chg_chip, battery_psd);
struct oplus_chg_chip *chip = g_charger_chip;
switch (psp) {
case POWER_SUPPLY_PROP_MMI_CHARGING_ENABLE:
charger_xlog_printk(CHG_LOG_CRTI, "set mmi_chg = [%d].\n", val->intval);
if (val->intval == 0) {
if(chip->unwakelock_chg == 1) {
ret = -EINVAL;
charger_xlog_printk(CHG_LOG_CRTI,
"unwakelock testing , this test not allowed.\n");
} else {
chip->prop_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
chip->mmi_chg = 0;
oplus_chg_turn_off_charging(chip);
if (oplus_vooc_get_fastchg_started() == true) {
oplus_vooc_turn_off_fastchg();
chip->mmi_fastchg = 0;
}
}
} else {
if(chip->unwakelock_chg == 1) {
ret = -EINVAL;
charger_xlog_printk(CHG_LOG_CRTI,
"unwakelock testing , this test not allowed.\n");
} else {
chip->mmi_chg = 1;
chip->prop_status = POWER_SUPPLY_STATUS_CHARGING;
if (chip->mmi_fastchg == 0) {
oplus_chg_clear_chargerid_info();
}
chip->mmi_fastchg = 1;
oplus_chg_turn_on_charging(chip);
}
}
break;
#ifdef CONFIG_OPLUS_SMOOTH_SOC
case POWER_SUPPLY_PROP_SMOOTH_SWITCH:
chip->smooth_switch = val->intval;
break;
#endif
#ifdef CONFIG_OPLUS_SMART_CHARGER_SUPPORT
case POWER_SUPPLY_PROP_COOL_DOWN:
oplus_smart_charge_by_cool_down(chip, val->intval);
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
if (chip->smart_charging_screenoff) {
oplus_smart_charge_by_shell_temp(chip, val->intval);
break;
} else {
ret = -EINVAL;
break;
}
#endif
#ifdef CONFIG_OPLUS_CHARGER_MTK
case POWER_SUPPLY_PROP_STOP_CHARGING_ENABLE:
charger_xlog_printk(CHG_LOG_CRTI, "set stop_chg = [%d].\n", val->intval);
if (val->intval == 0) {
chip->stop_chg = 0;
} else {
chip->stop_chg = 1;
}
break;
#endif
#ifdef CONFIG_OPLUS_SHIP_MODE_SUPPORT
case POWER_SUPPLY_PROP_SHIP_MODE:
chip->enable_shipmode = val->intval;
oplus_gauge_update_soc_smooth_parameter();
break;
#endif
#ifdef CONFIG_OPLUS_CALL_MODE_SUPPORT
case POWER_SUPPLY_PROP_CALL_MODE:
chip->calling_on = val->intval;
break;
#endif
#ifdef CONFIG_OPLUS_SHORT_C_BATT_CHECK
#ifdef CONFIG_OPLUS_SHORT_USERSPACE
case POWER_SUPPLY_PROP_SHORT_C_LIMIT_CHG:
printk(KERN_ERR "[OPLUS_CHG] [short_c_bat] set limit chg[%d]\n", !!val->intval);
chip->short_c_batt.limit_chg = !!val->intval;
//for userspace logic
if (!!val->intval == 0){
chip->short_c_batt.is_switch_on = 0;
}
break;
case POWER_SUPPLY_PROP_SHORT_C_LIMIT_RECHG:
printk(KERN_ERR "[OPLUS_CHG] [short_c_bat] set limit rechg[%d]\n", !!val->intval);
chip->short_c_batt.limit_rechg = !!val->intval;
break;
#else
case POWER_SUPPLY_PROP_SHORT_C_BATT_UPDATE_CHANGE:
printk(KERN_ERR "[OPLUS_CHG] [short_c_batt]: set update change[%d]\n", val->intval);
oplus_short_c_batt_update_change(chip, val->intval);
chip->short_c_batt.update_change = val->intval;
break;
case POWER_SUPPLY_PROP_SHORT_C_BATT_IN_IDLE:
printk(KERN_ERR "[OPLUS_CHG] [short_c_batt]: set in idle[%d]\n", !!val->intval);
chip->short_c_batt.in_idle = !!val->intval;
break;
#endif /*CONFIG_OPLUS_SHORT_USERSPACE*/
#endif /* CONFIG_OPLUS_SHORT_C_BATT_CHECK */
#ifdef CONFIG_OPLUS_SHORT_HW_CHECK
case POWER_SUPPLY_PROP_SHORT_C_HW_FEATURE:
printk(KERN_ERR "[OPLUS_CHG] [short_c_hw_check]: set is_feature_hw_on [%d]\n", val->intval);
chip->short_c_batt.is_feature_hw_on = val->intval;
break;
#endif /* CONFIG_OPLUS_SHORT_C_BATT_CHECK */
#ifdef CONFIG_OPLUS_SHORT_IC_CHECK
case POWER_SUPPLY_PROP_SHORT_C_IC_VOLT_THRESH:
if (chip) {
chip->short_c_batt.ic_volt_threshold = val->intval;
oplus_short_ic_set_volt_threshold(chip);
//pr_err("%s:[OPLUS_CHG][oplus_short_ic],ic_volt_threshold val->intval[%d]\n", __FUNCTION__, val->intval);
}
break;
#endif
default:
pr_err("set prop %d is not supported in batt\n", psp);
ret = -EINVAL;
break;
}
return ret;
}
#define OPLUS_MIDAS_CHG_DEBUG 1
#ifdef OPLUS_MIDAS_CHG_DEBUG
#define midas_debug(fmt, args...) \
pr_notice("[OPLUS_MIDAS_CHG_DEBUG]" fmt, ##args)
#else
#define midas_debug(fmt, args...)
#endif /* OPLUS_MIDAS_CHG_DEBUG */
static struct oplus_midas_chg {
int cali_passed_chg;
int passed_chg;
int accu_delta;
int prev_chg_stat; /* 1--charger-on, 0 -- otherwise */
unsigned int reset_counts;
} midas_chg;
static void oplus_midas_chg_info(const char *name)
{
midas_debug("%s: passedchg=%d, realpassedchg=%d,"
"accu_delta=%d, prev_chg_stat=%d, reset_counts=%u\n",
name, midas_chg.cali_passed_chg, midas_chg.passed_chg,
midas_chg.accu_delta, midas_chg.prev_chg_stat, midas_chg.reset_counts);
}
/* TODO: how to determine passedchg is reset precisely ? */
#define __abs(a, b) ((a > b) ? (a - b) : (b - a))
#define ZEROTH 5
#define COMSUMETH 10
static bool oplus_midas_passedchg_reset(int prev, int val)
{
if(__abs(val, prev) > COMSUMETH) {
return true;
} else if (__abs(val, 0) > ZEROTH) {
return false;
}
if(prev < 0 && val - prev >= ZEROTH) {
return true;
}
if(prev >= 0 && val < prev) {
return true;
}
return false;
}
static void oplus_midas_chg_data_init(void)
{
int val, ret;
midas_chg.accu_delta = 0;
midas_chg.reset_counts = 0;
if(oplus_vooc_get_allow_reading() == true) {
ret = oplus_gauge_get_passedchg(&val);
if (ret) {
pr_err("%s: get passedchg error %d\n", __FUNCTION__, val);
midas_chg.cali_passed_chg = midas_chg.passed_chg = 0;
} else {
midas_chg.cali_passed_chg = midas_chg.passed_chg = val;
}
} else {
pr_err("%s: not allow reading", __FUNCTION__);
}
}
static void oplus_midas_chg_processing(struct oplus_chg_chip *chip)
{
static int inited = 0;
int val, ret = 0;
if (!inited) {
oplus_midas_chg_data_init();
inited = 1;
return;
}
if (chip->charger_exist) {
midas_chg.prev_chg_stat = 1;
oplus_midas_chg_info(__FUNCTION__);
return;
}
if(oplus_vooc_get_allow_reading() == true) {
ret = oplus_gauge_get_passedchg(&val);
if (ret) {
pr_err("%s: get passedchg error %d\n", __FUNCTION__, val);
return;
}
} else {
pr_err("%s: not allow reading", __FUNCTION__);
}
if (midas_chg.prev_chg_stat) {
/* re-init passedchg after charge */
midas_chg.cali_passed_chg = midas_chg.passed_chg = val;
midas_chg.accu_delta = 0;
midas_chg.prev_chg_stat = 0;
} else {
if (oplus_midas_passedchg_reset(midas_chg.passed_chg, val)) {
/* handling passedchg reset ... */
midas_chg.cali_passed_chg += midas_chg.accu_delta;
midas_chg.reset_counts++;
} else {
/* accumulate normally */
midas_chg.accu_delta = val - midas_chg.passed_chg;
midas_chg.cali_passed_chg += midas_chg.accu_delta;
}
midas_chg.passed_chg = val;
}
oplus_midas_chg_info(__FUNCTION__);
}
int oplus_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
int ret = 0;
//struct oplus_chg_chip *chip = container_of(psy->desc, struct oplus_chg_chip, battery_psd);
struct oplus_chg_chip *chip = g_charger_chip;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
if (oplus_chg_show_vooc_logo_ornot() == 1) {
if(chip->new_ui_warning_support
&& (chip->tbatt_status == BATTERY_STATUS__WARM_TEMP && chip->batt_full))
val->intval = chip->prop_status;
else
val->intval = POWER_SUPPLY_STATUS_CHARGING;
} else if (!chip->authenticate) {
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
} else {
val->intval = chip->prop_status == POWER_SUPPLY_STATUS_NOT_CHARGING ? POWER_SUPPLY_STATUS_DISCHARGING : chip->prop_status;
}
break;
case POWER_SUPPLY_PROP_HEALTH:
val->intval = oplus_chg_get_prop_batt_health(chip);
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = chip->batt_exist;
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break;
case POWER_SUPPLY_PROP_CAPACITY:
if(chip->vooc_show_ui_soc_decimal == true && chip->decimal_control) {
val->intval = (chip->ui_soc_integer + chip->ui_soc_decimal)/1000;
} else {
val->intval = chip->ui_soc;
}
if(val->intval > 100) {
val->intval = 100;
}
break;
#ifdef CONFIG_OPLUS_CHIP_SOC_NODE
case POWER_SUPPLY_PROP_CHIP_SOC:
val->intval = chip->soc;
break;
#endif
#ifdef CONFIG_OPLUS_SMOOTH_SOC
case POWER_SUPPLY_PROP_SMOOTH_SOC:
val->intval = chip->smooth_soc;
break;
case POWER_SUPPLY_PROP_SMOOTH_SWITCH:
val->intval = chip->smooth_switch;
break;
#endif
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
#ifdef CONFIG_OPLUS_CHARGER_MTK
val->intval = chip->batt_volt;
#else
val->intval = chip->batt_volt * 1000;
#endif
break;
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
#ifdef CONFIG_OPLUS_CHARGER_MTK
val->intval = chip->batt_volt_min;
#else
val->intval = chip->batt_volt_min * 1000;
#endif
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
if (oplus_vooc_get_fastchg_started() == true) {
chip->icharging = oplus_gauge_get_prev_batt_current();
} else {
chip->icharging = oplus_gauge_get_batt_current();
}
val->intval = chip->icharging;
break;
case POWER_SUPPLY_PROP_TEMP:
if (oplus_vooc_get_fastchg_started() == true) {
val->intval = chip->tbatt_temp - chip->offset_temp;
} else {
val->intval = chip->tbatt_temp - chip->offset_temp;
}
break;
case POWER_SUPPLY_PROP_CHARGE_NOW:
if (oplus_vooc_get_fastchg_started() == true && (chip->vbatt_num == 2)
&& oplus_vooc_get_fast_chg_type() != CHARGER_SUBTYPE_FASTCHG_VOOC) {
val->intval = 10000;
} else {
val->intval = chip->charger_volt;
}
break;
case POWER_SUPPLY_PROP_AUTHENTICATE:
val->intval = chip->authenticate;
break;
case POWER_SUPPLY_PROP_CHARGE_TIMEOUT:
val->intval = chip->chging_over_time;
break;
case POWER_SUPPLY_PROP_CHARGE_TECHNOLOGY:
val->intval = chip->vooc_project;
break;
case POWER_SUPPLY_PROP_FAST_CHARGE:
val->intval = oplus_chg_show_vooc_logo_ornot();
#ifdef CONFIG_OPLUS_CHARGER_MTK
if (val->intval) {
charger_xlog_printk(CHG_LOG_CRTI, "vooc_logo:%d\n", val->intval);
}
#endif
break;
case POWER_SUPPLY_PROP_MMI_CHARGING_ENABLE: /*add for MMI_CHG TEST*/
val->intval = chip->mmi_chg;
break;
#ifdef CONFIG_OPLUS_CHARGER_MTK
case POWER_SUPPLY_PROP_STOP_CHARGING_ENABLE:
val->intval = chip->stop_chg;
break;
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
val->intval = chip->ui_soc * chip->batt_capacity_mah * 1000 / 100;
break;
case POWER_SUPPLY_PROP_CURRENT_MAX:
val->intval = 2000;
break;
#endif
#ifndef CONFIG_OPLUS_SDM670_CHARGER
case POWER_SUPPLY_PROP_CHARGE_FULL:
val->intval = chip->batt_fcc;
break;
#endif
case POWER_SUPPLY_PROP_BATTERY_FCC:
val->intval = chip->batt_fcc;
break;
case POWER_SUPPLY_PROP_BATTERY_SOH:
val->intval = chip->batt_soh;
break;
case POWER_SUPPLY_PROP_BATTERY_CC:
val->intval = chip->batt_cc;
break;
case POWER_SUPPLY_PROP_BATTERY_RM:
if (oplus_vooc_get_fastchg_started() == true) {
chip->batt_rm = oplus_gauge_get_prev_remaining_capacity() * chip->vbatt_num;
} else {
chip->batt_rm = oplus_gauge_get_remaining_capacity() * chip->vbatt_num;
}
val->intval = chip->batt_rm;
break;
case POWER_SUPPLY_PROP_BATTERY_NOTIFY_CODE:
val->intval = chip->notify_code;
break;
#ifdef CONFIG_OPLUS_SMART_CHARGER_SUPPORT
case POWER_SUPPLY_PROP_COOL_DOWN:
val->intval = chip->cool_down;
break;
#endif
case POWER_SUPPLY_PROP_ADAPTER_FW_UPDATE:
val->intval = oplus_vooc_get_adapter_update_status();
break;
case POWER_SUPPLY_PROP_VOOCCHG_ING:
val->intval = oplus_vooc_get_fastchg_ing();
#ifndef CONFIG_OPLUS_CHARGER_MTK
#ifndef WPC_NEW_INTERFACE
if (!val->intval && chip->wireless_support) {
val->intval = oplus_wpc_get_fast_charging();
}
#else
if (!val->intval && chip->wireless_support) {
val->intval = oplus_wpc_get_status();
}
#endif
#endif
break;
#ifdef CONFIG_OPLUS_CHECK_CHARGERID_VOLT
case POWER_SUPPLY_PROP_CHARGERID_VOLT:
val->intval = chip->chargerid_volt;
break;
#endif
#ifdef CONFIG_OPLUS_SHIP_MODE_SUPPORT
case POWER_SUPPLY_PROP_SHIP_MODE:
val->intval = chip->enable_shipmode;
break;
#endif
#ifdef CONFIG_OPLUS_CALL_MODE_SUPPORT
case POWER_SUPPLY_PROP_CALL_MODE:
val->intval = chip->calling_on;
break;
#endif
#ifdef CONFIG_OPLUS_SHORT_C_BATT_CHECK
#ifdef CONFIG_OPLUS_SHORT_USERSPACE
case POWER_SUPPLY_PROP_SHORT_C_LIMIT_CHG:
val->intval = (int)chip->short_c_batt.limit_chg;
break;
case POWER_SUPPLY_PROP_SHORT_C_LIMIT_RECHG:
val->intval = (int)chip->short_c_batt.limit_rechg;
break;
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
val->intval = chip->limits.iterm_ma;
break;
case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
val->intval = 2000;
if (chip && chip->chg_ops->get_dyna_aicl_result) {
val->intval = chip->chg_ops->get_dyna_aicl_result();
}
break;
#else
case POWER_SUPPLY_PROP_SHORT_C_BATT_UPDATE_CHANGE:
val->intval = chip->short_c_batt.update_change;
break;
case POWER_SUPPLY_PROP_SHORT_C_BATT_IN_IDLE:
val->intval = (int)chip->short_c_batt.in_idle;
break;
case POWER_SUPPLY_PROP_SHORT_C_BATT_CV_STATUS:
val->intval = (int)oplus_short_c_batt_get_cv_status(chip);
break;
#endif /*CONFIG_OPLUS_SHORT_USERSPACE*/
#endif /* CONFIG_OPLUS_SHORT_C_BATT_CHECK */
#ifdef CONFIG_OPLUS_SHORT_HW_CHECK
case POWER_SUPPLY_PROP_SHORT_C_HW_FEATURE:
val->intval = chip->short_c_batt.is_feature_hw_on;
break;
case POWER_SUPPLY_PROP_SHORT_C_HW_STATUS:
val->intval = chip->short_c_batt.shortc_gpio_status;
break;
#endif /* CONFIG_OPLUS_SHORT_C_BATT_CHECK */
#ifdef CONFIG_OPLUS_SHORT_IC_CHECK
case POWER_SUPPLY_PROP_SHORT_C_IC_OTP_STATUS:
if (chip) {
val->intval = chip->short_c_batt.ic_short_otp_st;
}
break;
case POWER_SUPPLY_PROP_SHORT_C_IC_VOLT_THRESH:
if (chip) {
val->intval = chip->short_c_batt.ic_volt_threshold;
}
break;
case POWER_SUPPLY_PROP_SHORT_C_IC_OTP_VALUE:
if (chip) {
val->intval = oplus_short_ic_get_otp_error_value(chip);
}
break;
#endif
default:
pr_err("get prop %d is not supported in batt\n", psp);
ret = -EINVAL;
break;
}
return ret;
}
static ssize_t proc_batt_param_noplug_write(struct file *filp,
const char __user *buf, size_t len, loff_t *data)
{
return len;
}
static int noplug_temperature = 0;
static int noplug_batt_volt_max = 0;
static int noplug_batt_volt_min = 0;
static ssize_t proc_batt_param_noplug_read(struct file *filp,
char __user *buff, size_t count, loff_t *off) {
char page[256] = {0};
char read_data[128] = {0};
int len = 0;
sprintf(read_data, "%d %d %d", noplug_temperature,
noplug_batt_volt_max, noplug_batt_volt_min);
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static const struct file_operations batt_param_noplug_proc_fops = {
.write = proc_batt_param_noplug_write,
.read = proc_batt_param_noplug_read,
};
static int init_proc_batt_param_noplug(void)
{
struct proc_dir_entry *p = NULL;
p = proc_create("batt_param_noplug", 0664, NULL, &batt_param_noplug_proc_fops);
if (!p) {
chg_err("proc_create fail!\n");
}
return 0;
}
static ssize_t proc_tbatt_pwroff_write(struct file *filp,
const char __user *buf, size_t len, loff_t *data)
{
char buffer[2] = {0};
if (len > 2) {
return -EFAULT;
}
if (copy_from_user(buffer, buf, 2)) {
chg_err("%s: error.\n", __func__);
return -EFAULT;
}
if (buffer[0] == '0') {
tbatt_pwroff_enable = 0;
} else {
tbatt_pwroff_enable = 1;
oplus_tbatt_power_off_task_wakeup();
}
chg_err("%s:tbatt_pwroff_enable = %d.\n", __func__, tbatt_pwroff_enable);
return len;
}
static ssize_t proc_tbatt_pwroff_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
char page[256] = {0};
char read_data[3] = {0};
int len = 0;
if (tbatt_pwroff_enable == 1) {
read_data[0] = '1';
} else {
read_data[0] = '0';
}
read_data[1] = '\0';
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static const struct file_operations tbatt_pwroff_proc_fops = {
.write = proc_tbatt_pwroff_write,
.read = proc_tbatt_pwroff_read,
};
static int init_proc_tbatt_pwroff(void)
{
struct proc_dir_entry *p = NULL;
p = proc_create("tbatt_pwroff", 0664, NULL, &tbatt_pwroff_proc_fops);
if (!p) {
chg_err("proc_create fail!\n");
}
return 0;
}
static ssize_t chg_log_write(struct file *filp,
const char __user *buff, size_t len, loff_t *data)
{
char write_data[32] = {0};
if (len > sizeof(write_data)) {
chg_err("bat_log_write error.\n");
return -EFAULT;
}
if (copy_from_user(&write_data, buff, len)) {
chg_err("bat_log_write error.\n");
return -EFAULT;
}
if (write_data[0] == '1') {
charger_xlog_printk(CHG_LOG_CRTI, "enable battery driver log system\n");
enable_charger_log = 1;
} else if ((write_data[0] >= '2') &&(write_data[0] <= '9')) {
charger_xlog_printk(CHG_LOG_CRTI, "enable battery driver log system:2\n");
enable_charger_log = 2;
} else {
charger_xlog_printk(CHG_LOG_CRTI, "Disable battery driver log system\n");
enable_charger_log = 0;
}
return len;
}
static ssize_t chg_log_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
char page[256] = {0};
char read_data[32] = {0};
int len = 0;
if (enable_charger_log == 1) {
read_data[0] = '1';
} else if (enable_charger_log == 2) {
read_data[0] = '2';
} else {
read_data[0] = '0';
}
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static const struct file_operations chg_log_proc_fops = {
.write = chg_log_write,
.read = chg_log_read,
};
static int init_proc_chg_log(void)
{
struct proc_dir_entry *p = NULL;
p = proc_create("charger_log", 0664, NULL, &chg_log_proc_fops);
if (!p) {
chg_err("proc_create chg_log_proc_fops fail!\n");
}
return 0;
}
static void oplus_chg_set_awake(struct oplus_chg_chip *chip, bool awake);
static ssize_t chg_cycle_write(struct file *file,
const char __user *buff, size_t count, loff_t *ppos)
{
char proc_chg_cycle_data[16];
if(count >= 16) {
count = 16;
}
if (copy_from_user(&proc_chg_cycle_data, buff, count)) {
chg_err("chg_cycle_write error.\n");
return -EFAULT;
}
if (strncmp(proc_chg_cycle_data, "en808", 5) == 0) {
if(g_charger_chip->unwakelock_chg == 1) {
charger_xlog_printk(CHG_LOG_CRTI, "unwakelock testing , this test not allowed.\n");
return -EPERM;
}
charger_xlog_printk(CHG_LOG_CRTI, "allow charging.\n");
g_charger_chip->chg_ops->charger_unsuspend();
g_charger_chip->chg_ops->charging_enable();
g_charger_chip->mmi_chg = 1;
g_charger_chip->stop_chg = 1;
if (g_charger_chip->dual_charger_support) {
g_charger_chip->slave_charger_enable = false;
oplus_chg_set_charging_current(g_charger_chip);
}
oplus_chg_set_input_current_limit(g_charger_chip);
} else if (strncmp(proc_chg_cycle_data, "dis808", 6) == 0) {
if(g_charger_chip->unwakelock_chg == 1) {
charger_xlog_printk(CHG_LOG_CRTI, "unwakelock testing , this test not allowed.\n");
return -EPERM;
}
charger_xlog_printk(CHG_LOG_CRTI, "not allow charging.\n");
g_charger_chip->chg_ops->charging_disable();
g_charger_chip->chg_ops->charger_suspend();
g_charger_chip->mmi_chg = 0;
g_charger_chip->stop_chg = 0;
} else if (strncmp(proc_chg_cycle_data, "wakelock", 8) == 0) {
charger_xlog_printk(CHG_LOG_CRTI, "set wakelock.\n");
g_charger_chip->unwakelock_chg = 0;
oplus_chg_set_awake(g_charger_chip, true);
g_charger_chip->chg_ops->charger_unsuspend();
g_charger_chip->chg_ops->charging_enable();
g_charger_chip->mmi_chg = 1;
g_charger_chip->stop_chg = 1;
g_charger_chip->chg_powersave = false;
if (g_charger_chip->chg_ops->oplus_chg_wdt_enable)
g_charger_chip->chg_ops->oplus_chg_wdt_enable(true);
if (g_charger_chip->mmi_fastchg == 0) {
oplus_chg_clear_chargerid_info();
}
g_charger_chip->mmi_fastchg = 1;
} else if (strncmp(proc_chg_cycle_data, "unwakelock", 10) == 0) {
charger_xlog_printk(CHG_LOG_CRTI, "set unwakelock.\n");
g_charger_chip->chg_ops->charging_disable();
//g_charger_chip->chg_ops->charger_suspend();
g_charger_chip->mmi_chg = 0;
g_charger_chip->stop_chg = 0;
g_charger_chip->unwakelock_chg = 1;
g_charger_chip->chg_powersave = true;
if (oplus_vooc_get_fastchg_started() == true) {
oplus_vooc_turn_off_fastchg();
g_charger_chip->mmi_fastchg = 0;
}
oplus_chg_set_awake(g_charger_chip, false);
if (g_charger_chip->chg_ops->oplus_chg_wdt_enable)
g_charger_chip->chg_ops->oplus_chg_wdt_enable(false);
} else if (strncmp(proc_chg_cycle_data, "powersave", 9) == 0) {
charger_xlog_printk(CHG_LOG_CRTI, "powersave: stop usbtemp monitor, etc.\n");
g_charger_chip->chg_powersave = true;
} else if (strncmp(proc_chg_cycle_data, "unpowersave", 11) == 0) {
charger_xlog_printk(CHG_LOG_CRTI, "unpowersave: start usbtemp monitor, etc.\n");
g_charger_chip->chg_powersave = false;
} else {
return -EFAULT;
}
return count;
}
static const struct file_operations chg_cycle_proc_fops = {
.write = chg_cycle_write,
.llseek = noop_llseek,
};
static void init_proc_chg_cycle(void)
{
if (!proc_create("charger_cycle",
S_IWUSR | S_IWGRP | S_IWOTH,
NULL, &chg_cycle_proc_fops)) {
chg_err("proc_create chg_cycle_proc_fops fail!\n");
}
}
static ssize_t critical_log_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
char page[256] = {0};
char read_data[32] = {0};
int len = 0;
// itoa(charger_abnormal_log, read_data, 10);
// sprintf(read_data,"%s",charger_abnormal_log);
if (charger_abnormal_log >= 10) {
charger_abnormal_log = 10;
}
read_data[0] = '0' + charger_abnormal_log % 10;
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static ssize_t critical_log_write(struct file *filp,
const char __user *buff, size_t len, loff_t *data)
{
char write_data[32] = {0};
int critical_log = 0;
if (len > sizeof(write_data)) {
return -EINVAL;
}
if (copy_from_user(&write_data, buff, len)) {
pr_err("bat_log_write error.\n");
return -EFAULT;
}
/* critical_log = atoi(write_data);*/
/* sprintf(critical_log,"%d",(void *)write_data);*/
write_data[len] = '\0';
if (write_data[len - 1] == '\n') {
write_data[len - 1] = '\0';
}
critical_log = (int)simple_strtoul(write_data, NULL, 10);
/* pr_err("%s:data=%s,critical_log=%d\n",__func__,write_data,critical_log);*/
if (critical_log > 256) {
critical_log = 256;
}
charger_abnormal_log = critical_log;
return len;
}
static const struct file_operations chg_critical_log_proc_fops = {
.write = critical_log_write,
.read = critical_log_read,
};
static void init_proc_critical_log(void)
{
struct proc_dir_entry *p = NULL;
p = proc_create("charger_critical_log", 0664, NULL,
&chg_critical_log_proc_fops);
if (!p) {
pr_err("proc_create chg_critical_log_proc_fops fail!\n");
}
}
#ifdef CONFIG_OPLUS_RTC_DET_SUPPORT
/* wenbin.liu add for det rtc reset */
static ssize_t rtc_reset_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
char page[256] = {0};
char read_data[32] = {0};
int len = 0;
int rc = 0;
if (!g_charger_chip) {
return -EFAULT;
} else {
rc = g_charger_chip->chg_ops->check_rtc_reset();
}
if (rc < 0 || rc >1) {
rc = 0;
}
read_data[0] = '0' + rc % 10;
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static const struct file_operations rtc_reset_det_fops = {
.read = rtc_reset_read,
};
static void init_proc_rtc_det(void)
{
struct proc_dir_entry *p = NULL;
p = proc_create("rtc_reset", 0664, NULL, &rtc_reset_det_fops);
if (!p) {
pr_err("proc_create rtc_reset_det_fops fail!\n");
}
}
static ssize_t vbat_low_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
char page[256] = {0};
char read_data[32] = {0};
int len = 0;
int rc = 0;
if (!g_charger_chip)
return -EFAULT;
if (vbatt_lowerthan_3300mv) {
rc = 1;
}
read_data[0] = '0' + rc % 10;
len = sprintf(page,"%s",read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff,page,(len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static const struct file_operations vbat_low_det_fops = {
.read = vbat_low_read,
};
static void init_proc_vbat_low_det(void)
{
struct proc_dir_entry *p = NULL;
p = proc_create("vbat_low", 0664, NULL, &vbat_low_det_fops);
if (!p) {
pr_err("proc_create rtc_reset_det_fops fail!\n");
}
}
#endif /* CONFIG_OPLUS_RTC_DET_SUPPORT */
int oplus_get_vbatt_pdqc_to_9v_thr(void)
{
struct oplus_chg_chip *chip = g_charger_chip;
int rc, ret;
if (chip->dev->of_node) {
rc = of_property_read_u32(chip->dev->of_node, "qcom,vbatt_pdqc_to_9v_thr",
&ret);
if (rc < 0) {
ret = 4000;
}
}else{
ret = 4000;
}
return ret;
}
static ssize_t proc_charger_factorymode_test_write
(struct file *file, const char __user *buf,
size_t count, loff_t *lo)
{
char buffer[2] = { 0 };
struct oplus_chg_chip *chip = g_charger_chip;
if (chip == NULL) {
chg_err("%s: g_charger_chip driver is not ready\n", __func__);
return -1;
}
if (count > 2) {
return -1;
}
if (copy_from_user(buffer, buf, 1)) {
chg_err("%s: error.\n", __func__);
return -1;
}
if(buffer[0] == '1'){
chip->limits.vbatt_pdqc_to_9v_thr = 4100;
chg_err("vbatt_pdqc_to_9v_thr=%d\n", chip->limits.vbatt_pdqc_to_9v_thr);
oplus_chg_pd_config(chip);
oplus_chg_qc_config(chip);
}
if(buffer[0] == '0'){
chip->limits.vbatt_pdqc_to_9v_thr = oplus_get_vbatt_pdqc_to_9v_thr();
chg_err("vbatt_pdqc_to_9v_thr=%d\n", chip->limits.vbatt_pdqc_to_9v_thr);
}
return count;
}
static const struct file_operations proc_charger_factorymode_test_ops =
{
.write = proc_charger_factorymode_test_write,
.open = simple_open,
.owner = THIS_MODULE,
};
static ssize_t proc_hmac_write(struct file *filp,
const char __user *buf, size_t len, loff_t *data)
{
struct oplus_chg_chip *chip = g_charger_chip;
char buffer[2] = {0};
if (NULL == chip)
return -EFAULT;
if (len > 2) {
return -EFAULT;
}
if (copy_from_user(buffer, buf, 2)) {
chg_err("%s: error.\n", __func__);
return -EFAULT;
}
if (buffer[0] == '0') {
chip->hmac = false;
} else {
chip->hmac = true;
}
return len;
}
static ssize_t proc_hmac_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
struct oplus_chg_chip *chip = g_charger_chip;
char page[256] = {0};
char read_data[3] = {0};
int len = 0;
if (NULL == chip)
return -EFAULT;
if (true == chip->hmac) {
read_data[0] = '1';
} else {
read_data[0] = '0';
}
read_data[1] = '\0';
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
chg_err("%s: copy_to_user error hmac = %d.\n", __func__, chip->hmac);
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static const struct file_operations hmac_proc_fops = {
.write = proc_hmac_write,
.read = proc_hmac_read,
.owner = THIS_MODULE,
};
static ssize_t proc_charger_input_current_now_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
char page[256] = {0};
char read_data[128] = {0};
int len = 0;
struct oplus_chg_chip *chip = g_charger_chip;
if(!chip) {
return 0;
}
sprintf(read_data, "%d", chip->ibus / 1000);
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static ssize_t proc_charger_passedchg_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
char page[256] = {0};
char read_data[128] = {0};
int len = 0;
struct oplus_chg_chip *chip = g_charger_chip;
if(!chip) {
return 0;
}
sprintf(read_data, "%d", midas_chg.cali_passed_chg);
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static ssize_t proc_charger_passedchg_reset_count_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
char page[256] = {0};
char read_data[128] = {0};
int len = 0;
struct oplus_chg_chip *chip = g_charger_chip;
if(!chip) {
return 0;
}
sprintf(read_data, "%d", midas_chg.reset_counts);
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static const struct file_operations proc_charger_input_current_now_ops =
{
.read = proc_charger_input_current_now_read,
.owner = THIS_MODULE,
};
static const struct file_operations proc_charger_passedchg_ops =
{
.read = proc_charger_passedchg_read,
.owner = THIS_MODULE,
};
static const struct file_operations proc_charger_passedchg_reset_count_ops =
{
.read = proc_charger_passedchg_reset_count_read,
.owner = THIS_MODULE,
};
static int init_charger_proc(struct oplus_chg_chip *chip)
{
int ret = 0;
struct proc_dir_entry *prEntry_da = NULL;
struct proc_dir_entry *prEntry_tmp = NULL;
prEntry_da = proc_mkdir("charger", NULL);
if (prEntry_da == NULL) {
ret = -1;
chg_debug("%s: Couldn't create charger proc entry\n",
__func__);
}
prEntry_tmp = proc_create_data("charger_factorymode_test", 0666, prEntry_da,
&proc_charger_factorymode_test_ops, chip);
if (prEntry_tmp == NULL) {
ret = -1;
chg_debug("%s: Couldn't create proc entry, %d\n", __func__,
__LINE__);
}
prEntry_tmp = proc_create_data("hmac", 0666, prEntry_da,
&hmac_proc_fops, chip);
if (prEntry_tmp == NULL) {
ret = -1;
chg_debug("%s: Couldn't create hmac proc entry, %d\n", __func__,
__LINE__);
}
prEntry_tmp = proc_create_data("input_current_now", 0666, prEntry_da,
&proc_charger_input_current_now_ops, chip);
prEntry_tmp = proc_create_data("passedchg", 0666, prEntry_da,
&proc_charger_passedchg_ops, chip);
prEntry_tmp = proc_create_data("passedchg_reset_count", 0666, prEntry_da,
&proc_charger_passedchg_reset_count_ops, chip);
return 0;
}
static ssize_t proc_ui_soc_decimal_write(struct file *filp,
const char __user *buf, size_t len, loff_t *data)
{
struct oplus_chg_chip *chip = g_charger_chip;
char buffer[2] = {0};
if (NULL == chip)
return -EFAULT;
if (len > 2) {
return -EFAULT;
}
if (copy_from_user(buffer, buf, 2)) {
chg_err("%s: error.\n", __func__);
return -EFAULT;
}
if (buffer[0] == '0') {
chip->boot_completed = false;
} else {
chip->boot_completed = true;
}
pr_err("proc_ui_soc_decimal_write write");
return len;
}
static ssize_t proc_ui_soc_decimal_read(struct file *filp,
char __user *buff, size_t count, loff_t *off)
{
char page[256] = {0};
char read_data[128] = {0};
int len = 0;
int schedule_work = 0;
int val;
bool svooc_is_control_by_vooc;
struct oplus_chg_chip *chip = g_charger_chip;
if(!chip) {
return 0;
}
if (chip->vooc_show_ui_soc_decimal) {
svooc_is_control_by_vooc = (chip->vbatt_num == 2 && oplus_vooc_get_fast_chg_type() == CHARGER_SUBTYPE_FASTCHG_VOOC);
if(svooc_is_control_by_vooc != true
&& chip->boot_completed != false && chip->calculate_decimal_time == 0 && oplus_chg_show_vooc_logo_ornot() == true) {
cancel_delayed_work_sync(&chip->ui_soc_decimal_work);
oplus_chg_ui_soc_decimal_init();
schedule_work = mod_delayed_work(system_wq, &chip->ui_soc_decimal_work, 0);
}
val = (chip->ui_soc_integer + chip->ui_soc_decimal) / 10;
if(chip->decimal_control == false) {
val = 0;
}
} else {
val = 0;
}
sprintf(read_data, "%d, %d", chip->init_decimal_ui_soc / 10, val);
pr_err("APK successful, %d", val);
len = sprintf(page, "%s", read_data);
if (len > *off) {
len -= *off;
} else {
len = 0;
}
if (copy_to_user(buff, page, (len < count ? len : count))) {
return -EFAULT;
}
*off += len < count ? len : count;
return (len < count ? len : count);
}
static const struct file_operations ui_soc_decimal_ops =
{
.write = proc_ui_soc_decimal_write,
.read = proc_ui_soc_decimal_read,
.owner = THIS_MODULE,
};
static int init_ui_soc_decimal_proc(struct oplus_chg_chip *chip)
{
int ret = 0;
struct proc_dir_entry *prEntry_tmp = NULL;
prEntry_tmp = proc_create_data("ui_soc_decimal", 0666, NULL,
&ui_soc_decimal_ops, chip);
if (prEntry_tmp == NULL) {
ret = -1;
chg_debug("%s: Couldn't create proc entry, %d\n", __func__,
__LINE__);
}
return 0;
}
void oplus_chg_ui_soc_decimal_init(void)
{
struct oplus_chg_chip *chip = g_charger_chip;
if (oplus_vooc_get_fastchg_started() == true) {
chip->batt_rm = oplus_gauge_get_prev_remaining_capacity() * chip->vbatt_num;
chip->batt_fcc = oplus_gauge_get_prev_batt_fcc() * chip->vbatt_num;
} else {
chip->batt_rm = oplus_gauge_get_remaining_capacity() * chip->vbatt_num;
chip->batt_fcc = oplus_gauge_get_batt_fcc() * chip->vbatt_num;
}
pr_err("[oplus_chg_ui_soc_decimal_init]!!!soc:%d", (int)((chip->batt_rm * 10000) / chip->batt_fcc));
if(chip->ui_soc == 100) {
chip->ui_soc_integer = chip->ui_soc *1000;
chip->ui_soc_decimal = 0;
} else {
chip->ui_soc_integer = chip->ui_soc *1000;
chip->ui_soc_decimal = chip->batt_rm * 100000 / chip->batt_fcc - (chip->batt_rm *100 / chip->batt_fcc) * 1000;
if((chip->ui_soc_integer + chip->ui_soc_decimal) > chip->last_decimal_ui_soc && chip->last_decimal_ui_soc != 0) {
chip->ui_soc_decimal = ((chip->last_decimal_ui_soc % 1000 - 100) > 0) ? (chip->last_decimal_ui_soc % 1000 - 100) : 0;
}
}
chip->init_decimal_ui_soc = chip->ui_soc_integer + chip->ui_soc_decimal;
if(chip->init_decimal_ui_soc > 100000) {
chip->init_decimal_ui_soc = 100000;
chip->ui_soc_integer = 100000;
chip->ui_soc_decimal = 0;
}
chip->decimal_control = true;
pr_err("[oplus_chg_ui_soc_decimal_init]!!! 2VBUS ui_soc_decimal:%d", chip->ui_soc_integer + chip->ui_soc_decimal);
chip->calculate_decimal_time = 1;
}
void oplus_chg_ui_soc_decimal_deinit(void)
{
struct oplus_chg_chip *chip = g_charger_chip;
chip->ui_soc_integer =(chip->ui_soc_integer + chip->ui_soc_decimal)/1000;
if(chip->ui_soc_integer != 0) {
chip->ui_soc = chip->ui_soc_integer;
}
chip->decimal_control = false;
pr_err("[oplus_chg_ui_soc_decimal_deinit] ui_soc:%d", chip->ui_soc);
chip->ui_soc_integer = 0;
chip->ui_soc_decimal = 0;
chip->init_decimal_ui_soc = 0;
}
#define MIN_DECIMAL_CURRENT 2000
static void oplus_chg_show_ui_soc_decimal(struct work_struct *work)
{
struct oplus_chg_chip *chip = g_charger_chip;
int speed, icharging;
int ratio = 1;
/*update the battery data*/
if (oplus_vooc_get_fastchg_started() == true) {
chip->batt_rm = oplus_gauge_get_prev_remaining_capacity() * chip->vbatt_num;
chip->batt_fcc = oplus_gauge_get_prev_batt_fcc() * chip->vbatt_num;
chip->icharging = oplus_gauge_get_batt_current();
} else {
chip->batt_rm = oplus_gauge_get_remaining_capacity() * chip->vbatt_num;
chip->batt_fcc = oplus_gauge_get_batt_fcc() * chip->vbatt_num;
chip->icharging = oplus_gauge_get_batt_current();
}
icharging = chip->icharging * (-1);
/*calculate the speed*/
if(chip->ui_soc - chip->soc > 5) {
ratio = 2;
} else {
ratio = 1;
}
if(icharging > 0) {
speed = 100000 * icharging * UPDATE_TIME * chip->vbatt_num / (chip->batt_fcc * 3600) / ratio;
pr_err("[oplus_chg_show_ui_soc_decimal] icharging = %d, batt_fcc :%d", chip->icharging, chip->batt_fcc);
} else {
/*speed = chip->ui_soc_decimal_speedmin / ratio;*/
speed = 0;
if(chip->batt_full) {
speed = chip->ui_soc_decimal_speedmin;
}
}
if (speed > 500) {
speed = 500;
}
chip->ui_soc_decimal += speed;
pr_err("[oplus_chg_ui_soc_decimal]chip->ui_soc_decimal+chip_ui_soc: %d , speed: %d, soc :%d\n ",
(chip->ui_soc_decimal + chip->ui_soc_integer), speed , ((chip->batt_rm * 10000) / chip->batt_fcc));
if(chip->ui_soc_integer + chip->ui_soc_decimal >= 100000) {
chip->ui_soc_integer = 100000;
chip->ui_soc_decimal = 0;
}
if(chip->calculate_decimal_time<= MAX_UI_DECIMAL_TIME) {
chip->calculate_decimal_time++;
schedule_delayed_work(&chip->ui_soc_decimal_work, msecs_to_jiffies(UPDATE_TIME * 1000));
} else {
oplus_chg_ui_soc_decimal_deinit();
}
}
static int charging_limit_time_show(struct seq_file *seq_filp, void *v)
{
seq_printf(seq_filp, "%d\n", g_charger_chip->limits.max_chg_time_sec);
return 0;
}
static int charging_limit_time_open(struct inode *inode, struct file *file)
{
int ret;
ret = single_open(file, charging_limit_time_show, NULL);
return ret;
}
static ssize_t charging_limit_time_write(struct file *filp,
const char __user *buff, size_t len, loff_t *data)
{
int limit_time;
char temp[16];
if (len > sizeof(temp)) {
return -EINVAL;
}
if (copy_from_user(temp, buff, len)) {
pr_err("charging_limit_time_write error.\n");
return -EFAULT;
}
sscanf(temp, "%d", &limit_time);
if (g_charger_chip) {
g_charger_chip->limits.max_chg_time_sec = limit_time;
printk(KERN_EMERG"charging_feature:max_chg_time_sec = %d\n",
g_charger_chip->limits.max_chg_time_sec);
}
return len;
}
static const struct file_operations charging_limit_time_fops = {
.open = charging_limit_time_open,
.write = charging_limit_time_write,
.read = seq_read,
};
static int charging_limit_current_show(struct seq_file *seq_filp, void *v)
{
seq_printf(seq_filp, "%d\n", g_charger_chip->limits.input_current_led_ma_high);
seq_printf(seq_filp, "%d\n", g_charger_chip->limits.input_current_led_ma_warm);
seq_printf(seq_filp, "%d\n", g_charger_chip->limits.input_current_led_ma_normal);
return 0;
}
static int charging_limit_current_open(struct inode *inode, struct file *file)
{
int ret;
ret = single_open(file, charging_limit_current_show, NULL);
return ret;
}
static ssize_t charging_limit_current_write(struct file *filp,
const char __user *buff, size_t len, loff_t *data)
{
int limit_current;
char temp[16];
if (len > sizeof(temp)) {
return -EINVAL;
}
if (copy_from_user(temp, buff, len)) {
pr_err("charging_limit_current_write error.\n");
return -EFAULT;
}
sscanf(temp, "%d", &limit_current);
if (g_charger_chip) {
g_charger_chip->limits.input_current_led_ma_high = limit_current;
g_charger_chip->limits.input_current_led_ma_warm = limit_current;
g_charger_chip->limits.input_current_led_ma_normal = limit_current;
printk(KERN_EMERG"charging_feature:limit_current = %d\n",limit_current);
}
return len;
}
static const struct file_operations charging_limit_current_fops = {
.open = charging_limit_current_open,
.write = charging_limit_current_write,
.read = seq_read,
};
static void init_proc_charging_feature(void)
{
struct proc_dir_entry *p_time = NULL;
struct proc_dir_entry *p_current = NULL;
p_time = proc_create("charging_limit_time", 0664, NULL,
&charging_limit_time_fops);
if (!p_time) {
pr_err("proc_create charging_feature_fops fail!\n");
}
p_current = proc_create("charging_limit_current", 0664, NULL,
&charging_limit_current_fops);
if (!p_current) {
pr_err("proc_create charging_feature_fops fail!\n");
}
}
/*ye.zhang add end*/
static void mmi_adapter_in_work_func(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct oplus_chg_chip *chip
= container_of(dwork, struct oplus_chg_chip, mmi_adapter_in_work);
chip->mmi_fastchg = 1;
charger_xlog_printk(CHG_LOG_CRTI, " mmi_fastchg\n");
}
static void oplus_mmi_fastchg_in(struct oplus_chg_chip *chip)
{
charger_xlog_printk(CHG_LOG_CRTI, " call\n");
schedule_delayed_work(&chip->mmi_adapter_in_work,
round_jiffies_relative(msecs_to_jiffies(2000)));
}
static void oplus_chg_awake_init(struct oplus_chg_chip *chip)
{
if (!chip) {
return;
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0))
wake_lock_init(&chip->suspend_lock, WAKE_LOCK_SUSPEND, "battery suspend wakelock");
#else
chip->suspend_ws = wakeup_source_register(NULL, "battery suspend wakelock");
#endif
}
static void oplus_chg_set_awake(struct oplus_chg_chip *chip, bool awake)
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0))
if (chip->unwakelock_chg == 1 && awake == true) {
charger_xlog_printk(CHG_LOG_CRTI,
"error, unwakelock testing, can not set wakelock.\n");
return;
}
if (awake){
wake_lock(&chip->suspend_lock);
} else {
wake_unlock(&chip->suspend_lock);
}
#else
static bool pm_flag = false;
if (chip->unwakelock_chg == 1 && awake == true) {
charger_xlog_printk(CHG_LOG_CRTI,
"error, unwakelock testing, can not set wakelock.\n");
return;
}
if (!chip || !chip->suspend_ws)
return;
if (awake && !pm_flag) {
pm_flag = true;
__pm_stay_awake(chip->suspend_ws);
} else if (!awake && pm_flag) {
__pm_relax(chip->suspend_ws);
pm_flag = false;
}
#endif
}
static int __ref shortc_thread_main(void *data)
{
struct oplus_chg_chip *chip = data;
struct cred *new;
int rc = 0;
new = prepare_creds();
if (!new) {
chg_err("init err\n");
rc = -1;
return rc;
}
new->fsuid = new->euid = KUIDT_INIT(1000);
commit_creds(new);
while (!kthread_should_stop()) {
set_current_state(TASK_RUNNING);
oplus_chg_short_c_battery_check(chip);
set_current_state(TASK_UNINTERRUPTIBLE);
schedule();
}
return rc;
}
int oplus_chg_init(struct oplus_chg_chip *chip)
{
int rc = 0;
char *thread_name = "shortc_thread";
struct power_supply *usb_psy;
struct power_supply *batt_psy;
struct power_supply *ac_psy;
if (!chip->chg_ops) {
dev_err(chip->dev, "charger operations cannot be NULL\n");
return -1;
}
oplus_chg_variables_init(chip);
oplus_get_smooth_soc_switch(chip);
oplus_chg_get_battery_data(chip);
usb_psy = power_supply_get_by_name("usb");
if (!usb_psy) {
dev_err(chip->dev, "USB psy not found; deferring probe\n");
/*return -EPROBE_DEFER;*/
goto power_psy_reg_failed;
}
chip->usb_psy = usb_psy;
ac_psy = power_supply_get_by_name("ac");
if (!ac_psy) {
dev_err(chip->dev, "ac psy not found; deferring probe\n");
goto power_psy_reg_failed;
}
chip->ac_psy = ac_psy;
batt_psy = power_supply_get_by_name("battery");
if (!batt_psy) {
dev_err(chip->dev, "battery psy not found; deferring probe\n");
goto power_psy_reg_failed;
}
chip->batt_psy = batt_psy;
#ifndef CONFIG_OPLUS_CHARGER_MTK
chip->pmic_spmi.psy_registered = true;
#endif
g_charger_chip = chip;
oplus_chg_awake_init(chip);
INIT_DELAYED_WORK(&chip->update_work, oplus_chg_update_work);
INIT_DELAYED_WORK(&chip->ui_soc_decimal_work, oplus_chg_show_ui_soc_decimal);
INIT_DELAYED_WORK(&chip->fastcheck_work, oppo_fastchg_check_work);
INIT_DELAYED_WORK(&chip->reset_adapter_work, oplus_chg_reset_adapter_work);
chip->shortc_thread = kthread_create(shortc_thread_main, (void *)chip, thread_name);
if (!chip->shortc_thread) {
chg_err("Can't create shortc_thread\n");
rc = -EPROBE_DEFER;
goto power_psy_reg_failed;
}
#ifdef CONFIG_FB
chip->chg_fb_notify.notifier_call = fb_notifier_callback;
#ifdef CONFIG_DRM_MSM
rc = msm_drm_register_client(&chip->chg_fb_notify);
#else
rc = fb_register_client(&chip->chg_fb_notify);
#endif /*CONFIG_DRM_MSM*/
if (rc) {
pr_err("Unable to register chg_fb_notify: %d\n", rc);
}
#endif
oplus_chg_debug_info_init();
init_proc_chg_log();
init_proc_chg_cycle();
init_proc_critical_log();
init_proc_tbatt_pwroff();
init_proc_batt_param_noplug();
#ifdef CONFIG_OPLUS_RTC_DET_SUPPORT
init_proc_rtc_det();
init_proc_vbat_low_det();
#endif
init_proc_charging_feature();
rc = init_ui_soc_decimal_proc(chip);
rc = init_charger_proc(chip);
/*ye.zhang add end*/
schedule_delayed_work(&chip->update_work, OPLUS_CHG_UPDATE_INIT_DELAY);
INIT_DELAYED_WORK(&chip->mmi_adapter_in_work, mmi_adapter_in_work_func);
chip->shell_themal = thermal_zone_get_zone_by_name("shell_back");
if (IS_ERR(chip->shell_themal)) {
chg_err("Can't get shell_back\n");
}
charger_xlog_printk(CHG_LOG_CRTI, " end\n");
return 0;
power_psy_reg_failed:
if (chip->ac_psy)
power_supply_unregister(chip->ac_psy);
if (chip->usb_psy)
power_supply_unregister(chip->usb_psy);
if (chip->batt_psy)
power_supply_unregister(chip->batt_psy);
charger_xlog_printk(CHG_LOG_CRTI, " Failed, rc = %d\n", rc);
return rc;
}
/*--------------------------------------------------------*/
int oplus_chg_parse_svooc_dt(struct oplus_chg_chip *chip)
{
int rc;
struct device_node *node = chip->dev->of_node;
if (!node) {
dev_err(chip->dev, "device tree info. missing\n");
return -EINVAL;
}
rc = of_property_read_u32(node, "qcom,vbatt_num", &chip->vbatt_num);
if (rc) {
chip->vbatt_num = 1;
}
rc = of_property_read_u32(node, "qcom,vooc_project", &chip->vooc_project);
if (rc < 0) {
chip->vooc_project = 0;
}
chip->platform_fg_flag = of_property_read_bool(node, "qcom,platform_fg_flag");
chg_err("oplus_parse_svooc_dt, chip->vbatt_num = %d,chip->vooc_project = %d.\n",
chip->vbatt_num,chip->vooc_project);
return 0;
}
int oplus_chg_parse_charger_dt(struct oplus_chg_chip *chip)
{
int rc;
struct device_node *node = chip->dev->of_node;
int batt_cold_degree_negative;
int batt_removed_degree_negative;
if (!node) {
dev_err(chip->dev, "device tree info. missing\n");
return -EINVAL;
}
rc = of_property_read_u32(node, "qcom,input_current_charger_ma",
&chip->limits.input_current_charger_ma);
if (rc) {
chip->limits.input_current_charger_ma
= OPCHG_INPUT_CURRENT_LIMIT_CHARGER_MA;
}
rc = of_property_read_u32(node, "qcom,pd_input_current_charger_ma",
&chip->limits.pd_input_current_charger_ma);
if (rc) {
chip->limits.pd_input_current_charger_ma
= OPCHG_INPUT_CURRENT_LIMIT_CHARGER_MA;
}
rc = of_property_read_u32(node, "qcom,qc_input_current_charger_ma",
&chip->limits.qc_input_current_charger_ma);
if (rc) {
chip->limits.qc_input_current_charger_ma
= OPCHG_INPUT_CURRENT_LIMIT_CHARGER_MA;
}
rc = of_property_read_u32(node, "qcom,input_current_usb_ma",
&chip->limits.input_current_usb_ma);
if (rc) {
chip->limits.input_current_usb_ma = OPCHG_INPUT_CURRENT_LIMIT_USB_MA;
}
rc = of_property_read_u32(node, "qcom,input_current_cdp_ma",
&chip->limits.input_current_cdp_ma);
if (rc) {
chip->limits.input_current_cdp_ma = OPCHG_INPUT_CURRENT_LIMIT_USB_MA;
}
if (get_eng_version() == HIGH_TEMP_AGING) {
chip->limits.input_current_led_ma = OPCHG_INPUT_CURRENT_LIMIT_CHARGER_MA;
chg_err(" CONFIG_HIGH_TEMP_VERSION enable here,led on current 2A \n");
} else {
rc = of_property_read_u32(node, "qcom,input_current_led_ma",
&chip->limits.input_current_led_ma);
if (rc) {
chip->limits.input_current_led_ma = OPCHG_INPUT_CURRENT_LIMIT_LED_MA;
}
}
if (get_eng_version() == HIGH_TEMP_AGING) {
chip->limits.input_current_led_ma_high = OPCHG_INPUT_CURRENT_LIMIT_CHARGER_MA;
chg_err(" CONFIG_HIGH_TEMP_VERSION enable here, led_ma_high on current 2A \n");
} else {
rc = of_property_read_u32(node, "qcom,input_current_led_ma_high",
&chip->limits.input_current_led_ma_high);
if (rc) {
chip->limits.input_current_led_ma_high = chip->limits.input_current_led_ma;
}
}
rc = of_property_read_u32(node, "qcom,led_high_bat_decidegc",
&chip->limits.led_high_bat_decidegc);
if (rc) {
chip->limits.led_high_bat_decidegc = 370;
}
if (get_eng_version() == HIGH_TEMP_AGING) {
chip->limits.input_current_led_ma_warm = OPCHG_INPUT_CURRENT_LIMIT_CHARGER_MA;
chg_err(" CONFIG_HIGH_TEMP_VERSION enable here, led_ma_warm on current 2A \n");
} else {
rc = of_property_read_u32(node, "qcom,input_current_led_ma_warm",
&chip->limits.input_current_led_ma_warm);
if (rc) {
chip->limits.input_current_led_ma_warm = chip->limits.input_current_led_ma;
}
}
rc = of_property_read_u32(node, "qcom,led_warm_bat_decidegc",
&chip->limits.led_warm_bat_decidegc);
if (rc) {
chip->limits.led_warm_bat_decidegc = 350;
}
if (get_eng_version() == HIGH_TEMP_AGING) {
chip->limits.input_current_led_ma_normal = OPCHG_INPUT_CURRENT_LIMIT_CHARGER_MA;
chg_err(" CONFIG_HIGH_TEMP_VERSION enable here, led_ma_normal on current 2A \n");
} else {
rc = of_property_read_u32(node, "qcom,input_current_led_ma_normal",
&chip->limits.input_current_led_ma_normal);
if (rc) {
chip->limits.input_current_led_ma_normal = chip->limits.input_current_led_ma;
}
}
rc = of_property_read_u32(node, "qcom,input_current_camera_ma",
&chip->limits.input_current_camera_ma);
if (rc) {
chip->limits.input_current_camera_ma = OPCHG_INPUT_CURRENT_LIMIT_CAMERA_MA;
}
chip->limits.iterm_disabled = of_property_read_bool(node, "qcom,iterm_disabled");
rc = of_property_read_u32(node, "qcom,iterm_ma", &chip->limits.iterm_ma);
if (rc < 0) {
chip->limits.iterm_ma = -EINVAL;
}
chip->smart_charging_screenoff = of_property_read_bool(node, "qcom,smart_charging_screenoff");
rc = of_property_read_u32(node, "qcom,input_current_calling_ma",
&chip->limits.input_current_calling_ma);
if (rc) {
chip->limits.input_current_calling_ma = OPCHG_INPUT_CURRENT_LIMIT_CALLING_MA;
}
rc = of_property_read_u32(node, "qcom,recharge-mv",
&chip->limits.recharge_mv);
if (rc < 0) {
chip->limits.recharge_mv = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,usb_high_than_bat_decidegc",
&chip->limits.usb_high_than_bat_decidegc);
if (rc < 0) {
chip->limits.usb_high_than_bat_decidegc = 100;
}
chg_err("usb_high_than_bat_decidegc:%d\n", chip->limits.usb_high_than_bat_decidegc);
/*-19C*/
rc = of_property_read_u32(node, "qcom,removed_bat_decidegc",
&batt_removed_degree_negative);
if (rc < 0) {
chip->limits.removed_bat_decidegc = -19;
} else {
chip->limits.removed_bat_decidegc = -batt_removed_degree_negative;
}
/*-3~0 C*/
if (get_eng_version() == HIGH_TEMP_AGING) {
chg_err(" CONFIG_HIGH_TEMP_VERSION enable here,disable low tbat chg \n");
batt_cold_degree_negative = 170;
chip->limits.cold_bat_decidegc = -batt_cold_degree_negative;
} else {
chg_err(" CONFIG_HIGH_TEMP_VERSION disabled\n");
rc = of_property_read_u32(node, "qcom,cold_bat_decidegc", &batt_cold_degree_negative);
if (rc < 0) {
chip->limits.cold_bat_decidegc = -EINVAL;
} else {
chip->limits.cold_bat_decidegc = -batt_cold_degree_negative;
}
}
rc = of_property_read_u32(node, "qcom,temp_cold_vfloat_mv",
&chip->limits.temp_cold_vfloat_mv);
if (rc < 0) {
chg_err(" temp_cold_vfloat_mv fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_cold_fastchg_current_ma",
&chip->limits.temp_cold_fastchg_current_ma);
if (rc < 0) {
chg_err(" temp_cold_fastchg_current_ma fail\n");
}
/*0~5 C*/
rc = of_property_read_u32(node, "qcom,little_cold_bat_decidegc",
&chip->limits.little_cold_bat_decidegc);
if (rc < 0) {
chip->limits.little_cold_bat_decidegc = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_little_cold_vfloat_mv",
&chip->limits.temp_little_cold_vfloat_mv);
if (rc < 0) {
chip->limits.temp_little_cold_vfloat_mv = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_little_cold_fastchg_current_ma",
&chip->limits.temp_little_cold_fastchg_current_ma);
if (rc < 0) {
chip->limits.temp_little_cold_fastchg_current_ma = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_little_cold_fastchg_current_ma_high",
&chip->limits.temp_little_cold_fastchg_current_ma_high);
if (rc < 0) {
chip->limits.temp_little_cold_fastchg_current_ma_high
= chip->limits.temp_little_cold_fastchg_current_ma;
}
rc = of_property_read_u32(node, "qcom,temp_little_cold_fastchg_current_ma_low",
&chip->limits.temp_little_cold_fastchg_current_ma_low);
if (rc < 0) {
chip->limits.temp_little_cold_fastchg_current_ma_low
= chip->limits.temp_little_cold_fastchg_current_ma;
}
rc = of_property_read_u32(node, "qcom,pd_temp_little_cold_fastchg_current_ma_high",
&chip->limits.pd_temp_little_cold_fastchg_current_ma_high);
if (rc < 0) {
chip->limits.pd_temp_little_cold_fastchg_current_ma_high
= chip->limits.temp_little_cold_fastchg_current_ma_high;
}
rc = of_property_read_u32(node, "qcom,pd_temp_little_cold_fastchg_current_ma_low",
&chip->limits.pd_temp_little_cold_fastchg_current_ma_low);
if (rc < 0) {
chip->limits.pd_temp_little_cold_fastchg_current_ma_low
= chip->limits.temp_little_cold_fastchg_current_ma_low;
}
rc = of_property_read_u32(node, "qcom,qc_temp_little_cold_fastchg_current_ma_high",
&chip->limits.qc_temp_little_cold_fastchg_current_ma_high);
if (rc < 0) {
chip->limits.qc_temp_little_cold_fastchg_current_ma_high
= chip->limits.temp_little_cold_fastchg_current_ma_high;
}
rc = of_property_read_u32(node, "qcom,qc_temp_little_cold_fastchg_current_ma_low",
&chip->limits.qc_temp_little_cold_fastchg_current_ma_low);
if (rc < 0) {
chip->limits.qc_temp_little_cold_fastchg_current_ma_low
= chip->limits.temp_little_cold_fastchg_current_ma_low;
}
/*5~12 C*/
rc = of_property_read_u32(node, "qcom,cool_bat_decidegc",
&chip->limits.cool_bat_decidegc);
if (rc < 0) {
chip->limits.cool_bat_decidegc = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_cool_vfloat_mv",
&chip->limits.temp_cool_vfloat_mv);
if (rc < 0) {
chip->limits.temp_cool_vfloat_mv = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_cool_fastchg_current_ma_high",
&chip->limits.temp_cool_fastchg_current_ma_high);
if (rc < 0) {
chip->limits.temp_cool_fastchg_current_ma_high = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_cool_fastchg_current_ma_low",
&chip->limits.temp_cool_fastchg_current_ma_low);
if (rc < 0) {
chip->limits.temp_cool_fastchg_current_ma_low = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,pd_temp_cool_fastchg_current_ma_high",
&chip->limits.pd_temp_cool_fastchg_current_ma_high);
if (rc < 0) {
chip->limits.pd_temp_cool_fastchg_current_ma_high
= chip->limits.temp_cool_fastchg_current_ma_high;
}
rc = of_property_read_u32(node, "qcom,pd_temp_cool_fastchg_current_ma_low",
&chip->limits.pd_temp_cool_fastchg_current_ma_low);
if (rc < 0) {
chip->limits.pd_temp_cool_fastchg_current_ma_low
= chip->limits.temp_cool_fastchg_current_ma_low;
}
rc = of_property_read_u32(node, "qcom,qc_temp_cool_fastchg_current_ma_high",
&chip->limits.qc_temp_cool_fastchg_current_ma_high);
if (rc < 0) {
chip->limits.qc_temp_cool_fastchg_current_ma_high
= chip->limits.temp_cool_fastchg_current_ma_high;
}
rc = of_property_read_u32(node, "qcom,qc_temp_cool_fastchg_current_ma_low",
&chip->limits.qc_temp_cool_fastchg_current_ma_low);
if (rc < 0) {
chip->limits.qc_temp_cool_fastchg_current_ma_low
= chip->limits.temp_cool_fastchg_current_ma_low;
}
/*12~16 C*/
rc = of_property_read_u32(node, "qcom,little_cool_bat_decidegc",
&chip->limits.little_cool_bat_decidegc);
if (rc < 0) {
chip->limits.little_cool_bat_decidegc = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_little_cool_vfloat_mv",
&chip->limits.temp_little_cool_vfloat_mv);
if (rc < 0) {
chip->limits.temp_little_cool_vfloat_mv = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_little_cool_fastchg_current_ma",
&chip->limits.temp_little_cool_fastchg_current_ma);
if (rc < 0) {
chip->limits.temp_little_cool_fastchg_current_ma = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_little_cool_fastchg_current_ma_high",
&chip->limits.temp_little_cool_fastchg_current_ma_high);
if (rc < 0) {
chip->limits.temp_little_cool_fastchg_current_ma_high = chip->limits.temp_little_cool_fastchg_current_ma;
}
rc = of_property_read_u32(node, "qcom,temp_little_cool_fastchg_current_ma_low",
&chip->limits.temp_little_cool_fastchg_current_ma_low);
if (rc < 0) {
chip->limits.temp_little_cool_fastchg_current_ma_low = chip->limits.temp_little_cool_fastchg_current_ma;
}
rc = of_property_read_u32(node, "qcom,pd_temp_little_cool_fastchg_current_ma",
&chip->limits.pd_temp_little_cool_fastchg_current_ma);
if (rc < 0) {
chip->limits.pd_temp_little_cool_fastchg_current_ma
= chip->limits.temp_little_cool_fastchg_current_ma;
}
rc = of_property_read_u32(node, "qcom,qc_temp_little_cool_fastchg_current_ma",
&chip->limits.qc_temp_little_cool_fastchg_current_ma);
if (rc < 0) {
chip->limits.qc_temp_little_cool_fastchg_current_ma
= chip->limits.temp_little_cool_fastchg_current_ma;
}
/*16~45 C*/
rc = of_property_read_u32(node, "qcom,normal_bat_decidegc",
&chip->limits.normal_bat_decidegc);
if (rc < 0) {
chg_err(" normal_bat_decidegc fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_fastchg_current_ma",
&chip->limits.temp_normal_fastchg_current_ma);
if (rc) {
chip->limits.temp_normal_fastchg_current_ma = OPCHG_FAST_CHG_MAX_MA;
}
rc = of_property_read_u32(node, "qcom,temp_normal_vfloat_mv",
&chip->limits.temp_normal_vfloat_mv);
if (rc < 0) {
chip->limits.temp_normal_vfloat_mv = 4320;
}
rc = of_property_read_u32(node, "qcom,pd_temp_normal_fastchg_current_ma",
&chip->limits.pd_temp_normal_fastchg_current_ma);
if (rc) {
chip->limits.pd_temp_normal_fastchg_current_ma = OPCHG_FAST_CHG_MAX_MA;
}
rc = of_property_read_u32(node, "qcom,qc_temp_normal_fastchg_current_ma",
&chip->limits.qc_temp_normal_fastchg_current_ma);
if (rc) {
chip->limits.qc_temp_normal_fastchg_current_ma = OPCHG_FAST_CHG_MAX_MA;
}
/* 16C ~ 22C */
rc = of_property_read_u32(node, "qcom,normal_phase1_bat_decidegc",
&chip->limits.normal_phase1_bat_decidegc);
if (rc < 0) {
chg_err(" normal_phase1_bat_decidegc fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase1_vfloat_mv",
&chip->limits.temp_normal_phase1_vfloat_mv);
if (rc < 0) {
chg_err(" temp_normal_phase1_vfloat_mv fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase1_fastchg_current_ma",
&chip->limits.temp_normal_phase1_fastchg_current_ma);
if (rc < 0) {
chg_err(" temp_normal_phase1_fastchg_current_ma fail\n");
}
rc = of_property_read_u32(node, "qcom,normal_phase2_bat_decidegc",
&chip->limits.normal_phase2_bat_decidegc);
if (rc < 0) {
chg_err(" normal_phase2_bat_decidegc fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase2_vfloat_mv",
&chip->limits.temp_normal_phase2_vfloat_mv);
if (rc < 0) {
chg_err(" temp_normal_phase2_vfloat_mv fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase2_fastchg_current_ma_high",
&chip->limits.temp_normal_phase2_fastchg_current_ma_high);
if (rc < 0) {
chg_err(" temp_normal_phase2_fastchg_current_ma_high fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase2_fastchg_current_ma_low",
&chip->limits.temp_normal_phase2_fastchg_current_ma_low);
if (rc < 0) {
chg_err(" temp_normal_phase2_fastchg_current_ma_low fail\n");
}
rc = of_property_read_u32(node, "qcom,normal_phase3_bat_decidegc",
&chip->limits.normal_phase3_bat_decidegc);
if (rc < 0) {
chg_err(" normal_phase3_bat_decidegc fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase3_vfloat_mv",
&chip->limits.temp_normal_phase3_vfloat_mv);
if (rc < 0) {
chg_err(" temp_normal_phase3_vfloat_mv fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase3_fastchg_current_ma_high",
&chip->limits.temp_normal_phase3_fastchg_current_ma_high);
if (rc < 0) {
chg_err(" temp_normal_phase3_fastchg_current_ma_high fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase3_fastchg_current_ma_low",
&chip->limits.temp_normal_phase3_fastchg_current_ma_low);
if (rc < 0) {
chg_err(" temp_normal_phase3_fastchg_current_ma_low fail\n");
}
rc = of_property_read_u32(node, "qcom,normal_phase4_bat_decidegc",
&chip->limits.normal_phase4_bat_decidegc);
if (rc < 0) {
chg_err(" normal_phase4_bat_decidegc fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase4_vfloat_mv",
&chip->limits.temp_normal_phase4_vfloat_mv);
if (rc < 0) {
chg_err(" temp_normal_phase4_vfloat_mv fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase4_fastchg_current_ma_high",
&chip->limits.temp_normal_phase4_fastchg_current_ma_high);
if (rc < 0) {
chg_err(" temp_normal_phase4_fastchg_current_ma_high fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase4_fastchg_current_ma_low",
&chip->limits.temp_normal_phase4_fastchg_current_ma_low);
if (rc < 0) {
chg_err(" temp_normal_phase4_fastchg_current_ma_low fail\n");
}
rc = of_property_read_u32(node, "qcom,normal_phase5_bat_decidegc",
&chip->limits.normal_phase5_bat_decidegc);
if (rc < 0) {
chg_err(" normal_phase5_bat_decidegc fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase5_vfloat_mv",
&chip->limits.temp_normal_phase5_vfloat_mv);
if (rc < 0) {
chg_err(" temp_normal_phase5_vfloat_mv fail\n");
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase5_fastchg_current_ma",
&chip->limits.temp_normal_phase5_fastchg_current_ma);
if (rc < 0) {
chg_err(" temp_normal_phase5_fastchg_current_ma fail\n");
}
rc = of_property_read_u32(node, "qcom,normal_phase6_bat_decidegc",
&chip->limits.normal_phase6_bat_decidegc);
if (rc < 0) {
chip->limits.normal_phase6_bat_decidegc = 420;
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase6_vfloat_mv",
&chip->limits.temp_normal_phase6_vfloat_mv);
if (rc < 0) {
chip->limits.temp_normal_phase6_vfloat_mv = chip->limits.temp_normal_phase5_vfloat_mv;
}
rc = of_property_read_u32(node, "qcom,temp_normal_phase6_fastchg_current_ma",
&chip->limits.temp_normal_phase6_fastchg_current_ma);
if (rc < 0) {
chip->limits.temp_normal_phase6_fastchg_current_ma = chip->limits.temp_normal_phase5_fastchg_current_ma;
}
charger_xlog_printk(CHG_LOG_CRTI,
"normal_phase1_bat_decidegc = %d, \
temp_normal_phase1_vfloat_mv = %d, \
temp_normal_phase1_fastchg_current_ma = %d, \
normal_phase2_bat_decidegc = %d, \
temp_normal_phase2_vfloat_mv = %d, \
temp_normal_phase2_fastchg_current_ma_high = %d, \
temp_normal_phase2_fastchg_current_ma_low = %d, \
normal_phase3_bat_decidegc = %d, \
temp_normal_phase3_vfloat_mv = %d, \
temp_normal_phase3_fastchg_current_ma_high = %d, \
temp_normal_phase3_fastchg_current_ma_low = %d, \
normal_phase4_bat_decidegc = %d, \
temp_normal_phase4_vfloat_mv = %d, \
temp_normal_phase4_fastchg_current_ma_high = %d, \
temp_normal_phase4_fastchg_current_ma_low = %d, \
normal_phase5_bat_decidegc = %d, \
temp_normal_phase5_vfloat_mv = %d, \
temp_normal_phase5_fastchg_current_ma = %d, \
normal_phase6_bat_decidegc = %d, \
temp_normal_phase6_vfloat_mv = %d, \
temp_normal_phase6_fastchg_current_ma = %d\n",
chip->limits.normal_phase1_bat_decidegc,
chip->limits.temp_normal_phase1_vfloat_mv,
chip->limits.temp_normal_phase1_fastchg_current_ma,
chip->limits.normal_phase2_bat_decidegc,
chip->limits.temp_normal_phase2_vfloat_mv,
chip->limits.temp_normal_phase2_fastchg_current_ma_high,
chip->limits.temp_normal_phase2_fastchg_current_ma_low,
chip->limits.normal_phase3_bat_decidegc,
chip->limits.temp_normal_phase3_vfloat_mv,
chip->limits.temp_normal_phase3_fastchg_current_ma_high,
chip->limits.temp_normal_phase3_fastchg_current_ma_low,
chip->limits.normal_phase4_bat_decidegc,
chip->limits.temp_normal_phase4_vfloat_mv,
chip->limits.temp_normal_phase4_fastchg_current_ma_high,
chip->limits.temp_normal_phase4_fastchg_current_ma_low,
chip->limits.normal_phase5_bat_decidegc,
chip->limits.temp_normal_phase5_vfloat_mv,
chip->limits.temp_normal_phase5_fastchg_current_ma,
chip->limits.normal_phase6_bat_decidegc,
chip->limits.temp_normal_phase6_vfloat_mv,
chip->limits.temp_normal_phase6_fastchg_current_ma);
/*45~55 C*/
rc = of_property_read_u32(node, "qcom,warm_bat_decidegc",
&chip->limits.warm_bat_decidegc);
if (rc < 0) {
chip->limits.warm_bat_decidegc = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_warm_vfloat_mv",
&chip->limits.temp_warm_vfloat_mv);
if (rc < 0) {
chip->limits.temp_warm_vfloat_mv = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,temp_warm_fastchg_current_ma",
&chip->limits.temp_warm_fastchg_current_ma);
if (rc < 0) {
chip->limits.temp_warm_fastchg_current_ma = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,pd_temp_warm_fastchg_current_ma",
&chip->limits.pd_temp_warm_fastchg_current_ma);
if (rc < 0) {
chip->limits.pd_temp_warm_fastchg_current_ma
= chip->limits.temp_warm_fastchg_current_ma;
}
rc = of_property_read_u32(node, "qcom,qc_temp_warm_fastchg_current_ma",
&chip->limits.qc_temp_warm_fastchg_current_ma);
if (rc < 0) {
chip->limits.qc_temp_warm_fastchg_current_ma
= chip->limits.temp_warm_fastchg_current_ma;
}
rc = of_property_read_u32(node, "qcom,temp_warm_fastchg_current_ma_led_on",
&chip->limits.temp_warm_fastchg_current_ma_led_on);
if (rc < 0) {
chip->limits.temp_warm_fastchg_current_ma_led_on
= chip->limits.temp_warm_fastchg_current_ma;
}
/*>55 C*/
rc = of_property_read_u32(node, "qcom,hot_bat_decidegc",
&chip->limits.hot_bat_decidegc);
if (rc < 0) {
chip->limits.hot_bat_decidegc = -EINVAL;
}
/*offset temperature, only for userspace, default 0*/
rc = of_property_read_u32(node, "qcom,offset_temp", &chip->offset_temp);
if (rc < 0) {
chip->offset_temp = 0;
}
/*non standard battery*/
rc = of_property_read_u32(node, "qcom,non_standard_vfloat_mv",
&chip->limits.non_standard_vfloat_mv);
if (rc < 0) {
chip->limits.non_standard_vfloat_mv = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,non_standard_fastchg_current_ma",
&chip->limits.non_standard_fastchg_current_ma);
if (rc < 0) {
chip->limits.non_standard_fastchg_current_ma = -EINVAL;
}
/*short circuit battery*/
rc = of_property_read_u32(node, "qcom,short_c_bat_cv_mv",
&chip->short_c_batt.short_c_bat_cv_mv);
if (rc < 0) {
chip->short_c_batt.short_c_bat_cv_mv = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,short_c_bat_vfloat_mv",
&chip->limits.short_c_bat_vfloat_mv);
if (rc < 0) {
chip->limits.short_c_bat_vfloat_mv = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,short_c_bat_fastchg_current_ma",
&chip->limits.short_c_bat_fastchg_current_ma);
if (rc < 0) {
chip->limits.short_c_bat_fastchg_current_ma = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,short_c_bat_vfloat_sw_limit",
&chip->limits.short_c_bat_vfloat_sw_limit);
if (rc < 0) {
chip->limits.short_c_bat_vfloat_sw_limit = -EINVAL;
}
/*vfloat_sw_limit*/
rc = of_property_read_u32(node, "qcom,non_standard_vfloat_sw_limit",
&chip->limits.non_standard_vfloat_sw_limit);
if (rc < 0) {
chip->limits.non_standard_vfloat_sw_limit = 3960;
}
rc = of_property_read_u32(node, "qcom,cold_vfloat_sw_limit",
&chip->limits.cold_vfloat_sw_limit);
if (rc < 0) {
chip->limits.cold_vfloat_sw_limit = 3960;
}
rc = of_property_read_u32(node, "qcom,little_cold_vfloat_sw_limit",
&chip->limits.little_cold_vfloat_sw_limit);
if (rc < 0) {
chip->limits.little_cold_vfloat_sw_limit = 4330;
}
rc = of_property_read_u32(node, "qcom,cool_vfloat_sw_limit",
&chip->limits.cool_vfloat_sw_limit);
if (rc < 0) {
chip->limits.cool_vfloat_sw_limit = 4330;
}
rc = of_property_read_u32(node, "qcom,little_cool_vfloat_sw_limit",
&chip->limits.little_cool_vfloat_sw_limit);
if (rc < 0) {
chip->limits.little_cool_vfloat_sw_limit = 4330;
}
rc = of_property_read_u32(node, "qcom,normal_vfloat_sw_limit",
&chip->limits.normal_vfloat_sw_limit);
if (rc < 0) {
chip->limits.normal_vfloat_sw_limit = 4330;
}
rc = of_property_read_u32(node, "qcom,warm_vfloat_sw_limit",
&chip->limits.warm_vfloat_sw_limit);
if (rc < 0) {
chip->limits.warm_vfloat_sw_limit = 4060;
}
/*vfloat_over_sw_limit*/
chip->limits.sw_vfloat_over_protect_enable = of_property_read_bool(node,
"qcom,sw_vfloat_over_protect_enable");
rc = of_property_read_u32(node, "qcom,non_standard_vfloat_over_sw_limit",
&chip->limits.non_standard_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.non_standard_vfloat_over_sw_limit = 3980;
}
rc = of_property_read_u32(node, "qcom,cold_vfloat_over_sw_limit",
&chip->limits.cold_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.cold_vfloat_over_sw_limit = 3980;
}
rc = of_property_read_u32(node, "qcom,little_cold_vfloat_over_sw_limit",
&chip->limits.little_cold_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.little_cold_vfloat_over_sw_limit = 4390;
}
rc = of_property_read_u32(node, "qcom,cool_vfloat_over_sw_limit",
&chip->limits.cool_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.cool_vfloat_over_sw_limit = 4390;
}
rc = of_property_read_u32(node, "qcom,little_cool_vfloat_over_sw_limit",
&chip->limits.little_cool_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.little_cool_vfloat_over_sw_limit = 4390;
}
rc = of_property_read_u32(node, "qcom,normal_vfloat_over_sw_limit",
&chip->limits.normal_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.normal_vfloat_over_sw_limit = 4390;
}
rc = of_property_read_u32(node, "qcom,warm_vfloat_over_sw_limit",
&chip->limits.warm_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.warm_vfloat_over_sw_limit = 4080;
}
rc = of_property_read_u32(node, "qcom,charger_hv_thr",
&chip->limits.charger_hv_thr);
if (rc < 0) {
chip->limits.charger_hv_thr = 5800;
}
rc = of_property_read_u32(node, "qcom,charger_recv_thr",
&chip->limits.charger_recv_thr);
if (rc < 0) {
chip->limits.charger_recv_thr = 5800;
}
rc = of_property_read_u32(node, "qcom,charger_lv_thr",
&chip->limits.charger_lv_thr);
if (rc < 0) {
chip->limits.charger_lv_thr = 3400;
}
rc = of_property_read_u32(node, "qcom,vbatt_full_thr",
&chip->limits.vbatt_full_thr);
if (rc < 0) {
chip->limits.vbatt_full_thr = 4400;
}
rc = of_property_read_u32(node, "qcom,vbatt_hv_thr",
&chip->limits.vbatt_hv_thr);
if (rc < 0) {
chip->limits.vbatt_hv_thr = 4500;
}
rc = of_property_read_u32(node, "qcom,vfloat_step_mv",
&chip->limits.vfloat_step_mv);
if (rc < 0) {
chip->limits.vfloat_step_mv = 16;
}
rc = of_property_read_u32(node, "qcom,vbatt_power_off",
&chip->vbatt_power_off);
if (rc < 0) {
chip->vbatt_power_off = 3300;
}
rc = of_property_read_u32(node, "qcom,vbatt_soc_1",
&chip->vbatt_soc_1);
if (rc < 0) {
chip->vbatt_soc_1 = 3410;
}
rc = of_property_read_u32(node, "qcom,normal_vterm_hw_inc",
&chip->limits.normal_vterm_hw_inc);
if (rc < 0) {
chip->limits.normal_vterm_hw_inc = 18;
}
rc = of_property_read_u32(node, "qcom,non_normal_vterm_hw_inc",
&chip->limits.non_normal_vterm_hw_inc);
if (rc < 0) {
chip->limits.non_normal_vterm_hw_inc = 18;
}
rc = of_property_read_u32(node, "qcom,vbatt_pdqc_to_5v_thr",
&chip->limits.vbatt_pdqc_to_5v_thr);
if (rc < 0) {
chip->limits.vbatt_pdqc_to_5v_thr = -EINVAL;
}
rc = of_property_read_u32(node, "qcom,vbatt_pdqc_to_9v_thr",
&chip->limits.vbatt_pdqc_to_9v_thr);
if (rc < 0) {
chip->limits.vbatt_pdqc_to_9v_thr = 4000;
}
charger_xlog_printk(CHG_LOG_CRTI,
"vbatt_power_off = %d, \
vbatt_soc_1 = %d, \
normal_vterm_hw_inc = %d, \
, \
non_normal_vterm_hw_inc = %d, \
vbatt_pdqc_to_9v_thr = %d, \
vbatt_pdqc_to_5v_thr = %d\n",
chip->vbatt_power_off,
chip->vbatt_soc_1,
chip->limits.normal_vterm_hw_inc,
chip->limits.non_normal_vterm_hw_inc,
chip->limits.vbatt_pdqc_to_9v_thr,
chip->limits.vbatt_pdqc_to_5v_thr);
rc = of_property_read_u32(node, "qcom,ff1_normal_fastchg_ma",
&chip->limits.ff1_normal_fastchg_ma);
if (rc) {
chip->limits.ff1_normal_fastchg_ma = 1000;
}
rc = of_property_read_u32(node, "qcom,ff1_warm_fastchg_ma",
&chip->limits.ff1_warm_fastchg_ma);
if (rc) {
chip->limits.ff1_warm_fastchg_ma = chip->limits.ff1_normal_fastchg_ma;
}
rc = of_property_read_u32(node, "qcom,ffc2_temp_warm_decidegc",
&chip->limits.ffc2_temp_warm_decidegc);
if (rc) {
chip->limits.ffc2_temp_warm_decidegc = 350;
}
rc = of_property_read_u32(node, "qcom,ffc2_temp_high_decidegc",
&chip->limits.ffc2_temp_high_decidegc);
if (rc) {
chip->limits.ffc2_temp_high_decidegc = 400;
}
rc = of_property_read_u32(node, "qcom,ffc2_temp_low_decidegc",
&chip->limits.ffc2_temp_low_decidegc);
if (rc) {
chip->limits.ffc2_temp_low_decidegc = 160;
}
rc = of_property_read_u32(node, "qcom,ffc2_normal_fastchg_ma",
&chip->limits.ffc2_normal_fastchg_ma);
if (rc < 0) {
chip->limits.ffc2_normal_fastchg_ma = 700;
}
rc = of_property_read_u32(node, "qcom,ffc2_warm_fastchg_ma",
&chip->limits.ffc2_warm_fastchg_ma);
if (rc < 0) {
chip->limits.ffc2_warm_fastchg_ma = 750;
}
rc = of_property_read_u32(node, "qcom,ffc2_exit_step_ma",
&chip->limits.ffc2_exit_step_ma);
if (rc < 0) {
chip->limits.ffc2_exit_step_ma = 100;
}
rc = of_property_read_u32(node, "qcom,ffc2_warm_exit_step_ma",
&chip->limits.ffc2_warm_exit_step_ma);
if (rc < 0) {
chip->limits.ffc2_warm_exit_step_ma = chip->limits.ffc2_exit_step_ma;
}
rc = of_property_read_u32(node, "qcom,ff1_exit_step_ma",
&chip->limits.ff1_exit_step_ma);
if (rc < 0) {
chip->limits.ff1_exit_step_ma = 400;
}
rc = of_property_read_u32(node, "qcom,ff1_warm_exit_step_ma",
&chip->limits.ff1_warm_exit_step_ma);
if (rc < 0) {
chip->limits.ff1_warm_exit_step_ma = 350;
}
rc = of_property_read_u32(node, "qcom,ffc_normal_vfloat_sw_limit",
&chip->limits.ffc1_normal_vfloat_sw_limit);
if (rc < 0) {
chip->limits.ffc1_normal_vfloat_sw_limit = 4450;
}
rc = of_property_read_u32(node, "qcom,ffc_warm_vfloat_sw_limit",
&chip->limits.ffc1_warm_vfloat_sw_limit);
if (rc < 0) {
chip->limits.ffc1_warm_vfloat_sw_limit
= chip->limits.ffc1_normal_vfloat_sw_limit;
}
rc = of_property_read_u32(node, "qcom,ffc2_normal_vfloat_sw_limit",
&chip->limits.ffc2_normal_vfloat_sw_limit);
if (rc < 0) {
chip->limits.ffc2_normal_vfloat_sw_limit
= chip->limits.ffc1_normal_vfloat_sw_limit;
}
rc = of_property_read_u32(node, "qcom,ffc2_warm_vfloat_sw_limit",
&chip->limits.ffc2_warm_vfloat_sw_limit);
if (rc < 0) {
chip->limits.ffc2_warm_vfloat_sw_limit
= chip->limits.ffc2_normal_vfloat_sw_limit;
}
rc = of_property_read_u32(node, "qcom,ffc_temp_normal_vfloat_mv",
&chip->limits.ffc_temp_normal_vfloat_mv);
if (rc < 0) {
chip->limits.ffc_temp_normal_vfloat_mv = 4500;
}
rc = of_property_read_u32(node, "qcom,ffc1_temp_normal_vfloat_mv",
&chip->limits.ffc1_temp_normal_vfloat_mv);
if (rc < 0) {
chip->limits.ffc1_temp_normal_vfloat_mv
= chip->limits.ffc_temp_normal_vfloat_mv;
}
rc = of_property_read_u32(node, "qcom,ffc2_temp_normal_vfloat_mv",
&chip->limits.ffc2_temp_normal_vfloat_mv);
if (rc < 0) {
chip->limits.ffc2_temp_normal_vfloat_mv
= chip->limits.ffc_temp_normal_vfloat_mv;
}
rc = of_property_read_u32(node, "qcom,ffc_normal_vfloat_over_sw_limit",
&chip->limits.ffc_normal_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.ffc_normal_vfloat_over_sw_limit = 4500;
}
rc = of_property_read_u32(node, "qcom,ffc1_normal_vfloat_over_sw_limit",
&chip->limits.ffc1_normal_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.ffc1_normal_vfloat_over_sw_limit
= chip->limits.ffc_normal_vfloat_over_sw_limit;
}
rc = of_property_read_u32(node, "qcom,ffc2_normal_vfloat_over_sw_limit",
&chip->limits.ffc2_normal_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.ffc2_normal_vfloat_over_sw_limit
= chip->limits.ffc_normal_vfloat_over_sw_limit;
}
charger_xlog_printk(CHG_LOG_CRTI,
"ff1_normal_fastchg_ma = %d, \
ffc2_temp_warm_decidegc = %d, \
ffc2_temp_high_decidegc = %d, \
ffc2_normal_fastchg_ma = %d, \
chip->limits.ffc2_warm_fastchg_ma = %d, \
ffc2_exit_step_ma = %d, \
ffc_normal_vfloat_sw_limit = %d, \
ffc_warm_vfloat_sw_limit = %d, \
ffc2_normal_vfloat_sw_limit = %d, \
ffc2_warm_vfloat_sw_limit = %d, \
ffc1_temp_normal_vfloat_mv = %d, \
ffc2_temp_normal_vfloat_mv = %d, \
ffc_normal_vfloat_over_sw_limit = %d \
ffc2_temp_low_decidegc = %d \
limits.ff1_exit_step_ma = %d \
limits.ff1_warm_exit_step_ma = %d \
pd_input_current_charger_ma = %d \
qc_input_current_charger_ma = %d\n",
chip->limits.ff1_normal_fastchg_ma,
chip->limits.ffc2_temp_warm_decidegc,
chip->limits.ffc2_temp_high_decidegc,
chip->limits.ffc2_normal_fastchg_ma,
chip->limits.ffc2_warm_fastchg_ma,
chip->limits.ffc2_exit_step_ma,
chip->limits.ffc1_normal_vfloat_sw_limit,
chip->limits.ffc1_warm_vfloat_sw_limit,
chip->limits.ffc2_normal_vfloat_sw_limit,
chip->limits.ffc2_warm_vfloat_sw_limit,
chip->limits.ffc1_temp_normal_vfloat_mv,
chip->limits.ffc2_temp_normal_vfloat_mv,
chip->limits.ffc_normal_vfloat_over_sw_limit,
chip->limits.ffc2_temp_low_decidegc,
chip->limits.ff1_exit_step_ma,
chip->limits.ff1_warm_exit_step_ma,
chip->limits.pd_input_current_charger_ma,
chip->limits.qc_input_current_charger_ma);
rc = of_property_read_u32(node, "qcom,default_iterm_ma",
&chip->limits.default_iterm_ma);
if (rc < 0) {
chip->limits.default_iterm_ma = 100;
}
rc = of_property_read_u32(node, "qcom,default_temp_normal_fastchg_current_ma",
&chip->limits.default_temp_normal_fastchg_current_ma);
if (rc < 0) {
chip->limits.default_temp_normal_fastchg_current_ma = OPCHG_FAST_CHG_MAX_MA;
}
rc = of_property_read_u32(node, "qcom,default_normal_vfloat_sw_limit",
&chip->limits.default_normal_vfloat_sw_limit);
if (rc < 0) {
chip->limits.default_normal_vfloat_sw_limit = 4350;
}
rc = of_property_read_u32(node, "qcom,default_temp_normal_vfloat_mv",
&chip->limits.default_temp_normal_vfloat_mv);
if (rc < 0) {
chip->limits.default_temp_normal_vfloat_mv = 4370;
}
rc = of_property_read_u32(node, "qcom,default_normal_vfloat_over_sw_limit",
&chip->limits.default_normal_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.default_normal_vfloat_over_sw_limit = 4373;
}
charger_xlog_printk(CHG_LOG_CRTI,
"default_iterm_ma = %d, \
default_temp_normal_fastchg_current_ma = %d, \
default_normal_vfloat_sw_limit = %d, \
default_temp_normal_vfloat_mv = %d, \
default_normal_vfloat_over_sw_limit = %d\n",
chip->limits.default_iterm_ma,
chip->limits.default_temp_normal_fastchg_current_ma,
chip->limits.default_normal_vfloat_sw_limit,
chip->limits.default_temp_normal_vfloat_mv,
chip->limits.default_normal_vfloat_over_sw_limit);
rc = of_property_read_u32(node, "qcom,default_temp_little_cool_fastchg_current_ma",
&chip->limits.default_temp_little_cool_fastchg_current_ma);
if (rc < 0) {
chip->limits.default_temp_little_cool_fastchg_current_ma
= chip->limits.temp_little_cool_fastchg_current_ma;
}
rc = of_property_read_u32(node, "qcom,default_little_cool_vfloat_sw_limit",
&chip->limits.default_little_cool_vfloat_sw_limit);
if (rc < 0) {
chip->limits.default_little_cool_vfloat_sw_limit
= chip->limits.little_cool_vfloat_sw_limit;
}
rc = of_property_read_u32(node, "qcom,default_temp_little_cool_vfloat_mv",
&chip->limits.default_temp_little_cool_vfloat_mv);
if (rc < 0) {
chip->limits.default_temp_little_cool_vfloat_mv
= chip->limits.temp_little_cool_vfloat_mv;
}
rc = of_property_read_u32(node, "qcom,default_little_cool_vfloat_over_sw_limit",
&chip->limits.default_little_cool_vfloat_over_sw_limit);
if (rc < 0) {
chip->limits.default_little_cool_vfloat_over_sw_limit
= chip->limits.little_cool_vfloat_over_sw_limit;
}
charger_xlog_printk(CHG_LOG_CRTI,
"default_temp_little_cool_fastchg_current_ma = %d, \
default_little_cool_vfloat_sw_limit = %d, \
default_temp_little_cool_vfloat_mv = %d, \
default_little_cool_vfloat_over_sw_limit = %d\n",
chip->limits.default_temp_little_cool_fastchg_current_ma,
chip->limits.default_little_cool_vfloat_sw_limit,
chip->limits.default_temp_little_cool_vfloat_mv,
chip->limits.default_little_cool_vfloat_over_sw_limit);
chip->limits.default_temp_little_cold_fastchg_current_ma_high
= chip->limits.temp_little_cold_fastchg_current_ma_high;
chip->limits.default_temp_little_cold_fastchg_current_ma_low
= chip->limits.temp_little_cold_fastchg_current_ma_low;
chip->limits.default_temp_cool_fastchg_current_ma_high
= chip->limits.temp_cool_fastchg_current_ma_high;
chip->limits.default_temp_cool_fastchg_current_ma_low
= chip->limits.temp_cool_fastchg_current_ma_low;
chip->limits.default_temp_little_cool_fastchg_current_ma_high
= chip->limits.temp_little_cool_fastchg_current_ma_high;
chip->limits.default_temp_little_cool_fastchg_current_ma_low
= chip->limits.temp_little_cool_fastchg_current_ma_low;
chip->limits.default_temp_warm_fastchg_current_ma
= chip->limits.temp_warm_fastchg_current_ma;
chip->limits.default_input_current_charger_ma
= chip->limits.input_current_charger_ma;
rc = of_property_read_u32(node, "qcom,batt_capacity_mah",
&chip->batt_capacity_mah);
if (rc < 0) {
chip->batt_capacity_mah = 2000;
}
chip->chg_ctrl_by_vooc = of_property_read_bool(node, "qcom,chg_ctrl_by_vooc");
chip->chg_ctrl_by_vooc_default = of_property_read_bool(node, "qcom,chg_ctrl_by_vooc");
rc = of_property_read_u32(node, "qcom,input_current_vooc_ma_normal",
&chip->limits.input_current_vooc_ma_normal);
if (rc) {
chip->limits.input_current_vooc_ma_normal = 3600;
}
rc = of_property_read_u32(node, "qcom,input_current_vooc_led_ma_high",
&chip->limits.input_current_vooc_led_ma_high);
if (rc) {
chip->limits.input_current_vooc_led_ma_high = 1800;
}
rc = of_property_read_u32(node, "qcom,input_current_vooc_led_ma_warm",
&chip->limits.input_current_vooc_led_ma_warm);
if (rc) {
chip->limits.input_current_vooc_led_ma_warm = 1800;
}
rc = of_property_read_u32(node, "qcom,input_current_vooc_led_ma_normal",
&chip->limits.input_current_vooc_led_ma_normal);
if (rc) {
chip->limits.input_current_vooc_led_ma_normal = 1800;
}
rc = of_property_read_u32(node, "qcom,vooc_temp_bat_normal_decidegc",
&chip->limits.vooc_normal_bat_decidegc);
if (rc) {
chip->limits.vooc_normal_bat_decidegc = 340;
}
rc = of_property_read_u32(node, "qcom,input_current_vooc_ma_warm",
&chip->limits.input_current_vooc_ma_warm);
if (rc) {
chip->limits.input_current_vooc_ma_warm = 3000;
}
rc = of_property_read_u32(node, "qcom,vooc_temp_bat_warm_decidegc",
&chip->limits.vooc_warm_bat_decidegc);
if (rc) {
chip->limits.vooc_warm_bat_decidegc = 380;
}
rc = of_property_read_u32(node, "qcom,input_current_vooc_ma_high",
&chip->limits.input_current_vooc_ma_high);
if (rc) {
chip->limits.input_current_vooc_ma_high = 2600;
}
rc = of_property_read_u32(node, "qcom,vooc_temp_bat_hot_decidegc",
&chip->limits.vooc_high_bat_decidegc);
if (rc) {
chip->limits.vooc_high_bat_decidegc = 450;
}
rc = of_property_read_u32(node, "qcom,charger_current_vooc_ma_normal",
&chip->limits.charger_current_vooc_ma_normal);
if (rc) {
chip->limits.charger_current_vooc_ma_normal = 1000;
}
chip->limits.default_input_current_vooc_ma_high
= chip->limits.input_current_vooc_ma_high;
chip->limits.default_input_current_vooc_ma_warm
= chip->limits.input_current_vooc_ma_warm;
chip->limits.default_input_current_vooc_ma_normal
= chip->limits.input_current_vooc_ma_normal;
chip->limits.default_pd_input_current_charger_ma
= chip->limits.pd_input_current_charger_ma;
chip->limits.default_qc_input_current_charger_ma
= chip->limits.qc_input_current_charger_ma;
chip->suspend_after_full = of_property_read_bool(node, "qcom,suspend_after_full");
chip->check_batt_full_by_sw = of_property_read_bool(node, "qcom,check_batt_full_by_sw");
chip->external_gauge = of_property_read_bool(node, "qcom,external_gauge");
chip->fg_bcl_poll = of_property_read_bool(node, "qcom,fg_bcl_poll_enable");
chip->wireless_support = of_property_read_bool(node, "qcom,wireless_support");
chip->wpc_no_chargerpump = of_property_read_bool(node, "qcom,wpc_no_chargerpump");
chip->chg_ctrl_by_lcd = of_property_read_bool(node, "qcom,chg_ctrl_by_lcd");
chip->chg_ctrl_by_lcd_default = of_property_read_bool(node, "qcom,chg_ctrl_by_lcd");
chip->chg_ctrl_by_camera = of_property_read_bool(node, "qcom,chg_ctrl_by_camera");
chip->bq25890h_flag = of_property_read_bool(node,"qcom,bq25890_flag");
chip->chg_ctrl_by_calling = of_property_read_bool(node, "qcom,chg_ctrl_by_calling");
chip->ffc_support = of_property_read_bool(node, "qcom,ffc_support");
chip->dual_ffc = of_property_read_bool(node, "qcom,dual_ffc");
chip->new_ui_warning_support = of_property_read_bool(node, "qcom,new_ui_warning_support");
chip->recharge_after_full = of_property_read_bool(node, "recharge_after_full");
chip->smooth_switch = of_property_read_bool(node, "qcom,smooth_switch");
chip->limits.max_chg_time_sec = chip->batt_capacity_mah / 250 * 3600;
charger_xlog_printk(CHG_LOG_CRTI,
"input_current_charger_ma = %d, \
input_current_usb_ma = %d, \
input_current_led_ma = %d, \
input_current_led_ma_normal = %d, \
input_current_led_ma_warm = %d, \
input_current_led_ma_high = %d, \
temp_normal_fastchg_current_ma = %d, \
temp_normal_vfloat_mv = %d, \
iterm_ma = %d, \
recharge_mv = %d, \
cold_bat_decidegc = %d, \
temp_cold_vfloat_mv = %d, \
temp_cold_fastchg_current_ma = %d, \
little_cold_bat_decidegc = %d, \
temp_little_cold_vfloat_mv = %d, \
temp_little_cold_fastchg_current_ma = %d, \
cool_bat_decidegc = %d, \
temp_cool_vfloat_mv = %d, \
temp_cool_fastchg_current_ma_high = %d, \
temp_cool_fastchg_current_ma_low = %d, \
little_cool_bat_decidegc = %d, \
temp_little_cool_vfloat_mv = %d, \
temp_little_cool_fastchg_current_ma = %d, \
normal_bat_decidegc = %d, \
warm_bat_decidegc = %d, \
temp_warm_vfloat_mv = %d, \
temp_warm_fastchg_current_ma = %d, \
hot_bat_decidegc = %d, \
non_standard_vfloat_mv = %d, \
non_standard_fastchg_current_ma = %d, \
max_chg_time_sec = %d, \
charger_hv_thr = %d, \
charger_lv_thr = %d, \
vbatt_full_thr = %d, \
vbatt_hv_thr = %d, \
vfloat_step_mv = %d, \
vooc_project = %d, \
suspend_after_full = %d, \
ext_gauge = %d, \
sw_vfloat_enable = %d, \
chip->limits.temp_little_cold_fastchg_current_ma_low = %d, \
chip->limits.temp_little_cold_fastchg_current_ma_high = %d, \
chip->limits.charger_current_vooc_ma_normal = %d, \
chip->ffc_support = %d\
chip->dual_ffc = %d\
chip->new_ui_warning_support = %d\
chip->smooth_switch = %d\n",
chip->limits.input_current_charger_ma,
chip->limits.input_current_usb_ma,
chip->limits.input_current_led_ma,
chip->limits.input_current_led_ma_normal,
chip->limits.input_current_led_ma_warm,
chip->limits.input_current_led_ma_high,
chip->limits.temp_normal_fastchg_current_ma,
chip->limits.temp_normal_vfloat_mv,
chip->limits.iterm_ma,
chip->limits.recharge_mv,
chip->limits.cold_bat_decidegc,
chip->limits.temp_cold_vfloat_mv,
chip->limits.temp_cold_fastchg_current_ma,
chip->limits.little_cold_bat_decidegc,
chip->limits.temp_little_cold_vfloat_mv,
chip->limits.temp_little_cold_fastchg_current_ma,
chip->limits.cool_bat_decidegc,
chip->limits.temp_cool_vfloat_mv,
chip->limits.temp_cool_fastchg_current_ma_high,
chip->limits.temp_cool_fastchg_current_ma_low,
chip->limits.little_cool_bat_decidegc,
chip->limits.temp_little_cool_vfloat_mv,
chip->limits.temp_little_cool_fastchg_current_ma,
chip->limits.normal_bat_decidegc,
chip->limits.warm_bat_decidegc,
chip->limits.temp_warm_vfloat_mv,
chip->limits.temp_warm_fastchg_current_ma,
chip->limits.hot_bat_decidegc,
chip->limits.non_standard_vfloat_mv,
chip->limits.non_standard_fastchg_current_ma,
chip->limits.max_chg_time_sec,
chip->limits.charger_hv_thr,
chip->limits.charger_lv_thr,
chip->limits.vbatt_full_thr,
chip->limits.vbatt_hv_thr,
chip->limits.vfloat_step_mv,
chip->vooc_project,
chip->suspend_after_full,
chip->external_gauge,
chip->limits.sw_vfloat_over_protect_enable,
chip->limits.temp_little_cold_fastchg_current_ma_low,
chip->limits.temp_little_cold_fastchg_current_ma_high,
chip->limits.charger_current_vooc_ma_normal,
chip->ffc_support,
chip->dual_ffc,
chip->new_ui_warning_support,
chip->smooth_switch);
chip->dual_charger_support = of_property_read_bool(node, "qcom,dual_charger_support");
rc = of_property_read_u32(node, "qcom,slave_pct", &chip->slave_pct);
if (rc) {
chip->slave_pct = 50;
}
rc = of_property_read_u32(node, "qcom,slave_chg_enable_ma", &chip->slave_chg_enable_ma);
if (rc) {
chip->slave_chg_enable_ma = 2100;
}
rc = of_property_read_u32(node, "qcom,slave_chg_disable_ma", &chip->slave_chg_disable_ma);
if (rc) {
chip->slave_chg_disable_ma = 1700;
}
rc = of_property_read_u32(node, "qcom,usbtemp_batttemp_gap", &chip->usbtemp_batttemp_gap);
if (rc) {
chip->usbtemp_batttemp_gap = 17;
}
chip->vooc_show_ui_soc_decimal = of_property_read_bool(node, "qcom,vooc_show_ui_soc_decimal");
rc = of_property_read_u32(node, "qcom,ui_soc_decimal_speedmin", &chip->ui_soc_decimal_speedmin);
if (rc) {
chip->ui_soc_decimal_speedmin = 2;
}
charger_xlog_printk(CHG_LOG_CRTI,"dual_charger_support=%d, slave_pct=%d, slave_chg_enable_ma=%d, slave_chg_disable_ma=%d\n",
chip->dual_charger_support, chip->slave_pct, chip->slave_chg_enable_ma, chip->slave_chg_disable_ma);
return 0;
}
int oplus_chg_get_tbatt_normal_charging_current(struct oplus_chg_chip *chip)
{
int charging_current = OPLUS_CHG_DEFAULT_CHARGING_CURRENT;
switch (chip->tbatt_normal_status) {
case BATTERY_STATUS__NORMAL_PHASE1:
charging_current = chip->limits.temp_normal_phase1_fastchg_current_ma;
break;
case BATTERY_STATUS__NORMAL_PHASE2:
if (vbatt_higherthan_4180mv) {
charging_current = chip->limits.temp_normal_phase2_fastchg_current_ma_low;
} else {
charging_current = chip->limits.temp_normal_phase2_fastchg_current_ma_high;
}
break;
case BATTERY_STATUS__NORMAL_PHASE3:
if (vbatt_higherthan_4180mv) {
charging_current = chip->limits.temp_normal_phase3_fastchg_current_ma_low;
} else {
charging_current = chip->limits.temp_normal_phase3_fastchg_current_ma_high;
}
break;
case BATTERY_STATUS__NORMAL_PHASE4:
if (vbatt_higherthan_4180mv) {
charging_current = chip->limits.temp_normal_phase4_fastchg_current_ma_low;
} else {
charging_current = chip->limits.temp_normal_phase4_fastchg_current_ma_high;
}
break;
case BATTERY_STATUS__NORMAL_PHASE5:
charging_current = chip->limits.temp_normal_phase5_fastchg_current_ma;
break;
case BATTERY_STATUS__NORMAL_PHASE6:
charging_current = chip->limits.temp_normal_phase6_fastchg_current_ma;
break;
default:
break;
}
return charging_current;
}
static void oplus_chg_set_charging_current(struct oplus_chg_chip *chip)
{
int charging_current = OPLUS_CHG_DEFAULT_CHARGING_CURRENT;
#ifndef CONFIG_OPLUS_CHARGER_MTK
#ifndef WPC_NEW_INTERFACE
if (chip->wireless_support && oplus_wireless_charge_start() == true) {
chg_err(" test do not set ichging , wireless charge start \n");
return;
}
#else
if (oplus_wpc_get_status() != 0){
chg_err(" test do not set ichging , wireless charge start \n");
return;
}
#endif
#endif
switch (chip->tbatt_status) {
case BATTERY_STATUS__INVALID:
case BATTERY_STATUS__REMOVED:
case BATTERY_STATUS__LOW_TEMP:
case BATTERY_STATUS__HIGH_TEMP:
return;
case BATTERY_STATUS__COLD_TEMP:
charging_current = chip->limits.temp_cold_fastchg_current_ma;
break;
case BATTERY_STATUS__LITTLE_COLD_TEMP:
//charging_current = chip->limits.temp_little_cold_fastchg_current_ma;
if (vbatt_higherthan_4180mv) {
charging_current = chip->limits.temp_little_cold_fastchg_current_ma_low;
} else {
charging_current = chip->limits.temp_little_cold_fastchg_current_ma_high;
}
charger_xlog_printk(CHG_LOG_CRTI,
"vbatt_higherthan_4180mv [%d], charging_current[%d]\n",
vbatt_higherthan_4180mv, charging_current);
break;
case BATTERY_STATUS__COOL_TEMP:
if (vbatt_higherthan_4180mv) {
charging_current = chip->limits.temp_cool_fastchg_current_ma_low;
} else {
charging_current = chip->limits.temp_cool_fastchg_current_ma_high;
}
charger_xlog_printk(CHG_LOG_CRTI,
"vbatt_higherthan_4180mv [%d], charging_current[%d]\n",
vbatt_higherthan_4180mv, charging_current);
break;
case BATTERY_STATUS__LITTLE_COOL_TEMP:
if (chip->dual_charger_support) {
if (vbatt_higherthan_4180mv) {
charging_current = chip->limits.temp_little_cool_fastchg_current_ma_low;
} else {
charging_current = chip->limits.temp_little_cool_fastchg_current_ma_high;
}
charger_xlog_printk(CHG_LOG_CRTI,
"vbatt_higherthan_4180mv [%d], charging_current[%d]\n",
vbatt_higherthan_4180mv, charging_current);
} else {
charging_current = chip->limits.temp_little_cool_fastchg_current_ma;
}
break;
case BATTERY_STATUS__NORMAL:
if (chip->dual_charger_support) {
charging_current = oplus_chg_get_tbatt_normal_charging_current(chip);
}
else
charging_current = chip->limits.temp_normal_fastchg_current_ma;
break;
case BATTERY_STATUS__WARM_TEMP:
charging_current = chip->limits.temp_warm_fastchg_current_ma;
break;
default:
break;
}
if (((!chip->authenticate) || (!chip->hmac))
&& (charging_current > chip->limits.non_standard_fastchg_current_ma)) {
charging_current = chip->limits.non_standard_fastchg_current_ma;
charger_xlog_printk(CHG_LOG_CRTI,
"no high battery, set charging current = %d\n",
chip->limits.non_standard_fastchg_current_ma);
}
if (oplus_short_c_batt_is_prohibit_chg(chip)) {
if (charging_current > chip->limits.short_c_bat_fastchg_current_ma) {
charging_current = chip->limits.short_c_bat_fastchg_current_ma;
charger_xlog_printk(CHG_LOG_CRTI,
"short circuit battery, set charging current = %d\n",
chip->limits.short_c_bat_fastchg_current_ma);
}
}
if ((chip->chg_ctrl_by_lcd) && (chip->led_on) &&
(charging_current > chip->limits.temp_warm_fastchg_current_ma_led_on)) {
if (chip->tbatt_status == BATTERY_STATUS__WARM_TEMP){
charging_current = chip->limits.temp_warm_fastchg_current_ma_led_on;
}
if (chip->dual_charger_support && chip->tbatt_normal_status == BATTERY_STATUS__NORMAL_PHASE6) {
charging_current = chip->limits.temp_warm_fastchg_current_ma_led_on;
}
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY]LED ON, charging current: %d\n", charging_current);
}
if (charging_current == 0) {
return;
}
chip->chg_ops->charging_current_write_fast(charging_current);
}
void oplus_chg_set_input_current_limit(struct oplus_chg_chip *chip)
{
int current_limit = 0;
bool is_mcu_fastchg = false;
is_mcu_fastchg = (oplus_vooc_get_fastchg_started()
&&(chip->vbatt_num != 2 || oplus_vooc_get_fast_chg_type() != CHARGER_SUBTYPE_FASTCHG_VOOC));
if(is_mcu_fastchg) {
chg_err("MCU_READING_iic,return");
return;
}
#ifndef CONFIG_OPLUS_CHARGER_MTK
#ifndef WPC_NEW_INTERFACE
if (chip->wireless_support && oplus_wireless_charge_start() == true) {
chg_err(" test do not set ichging , wireless charge start \n");
return;
}
#else
if (oplus_wpc_get_status() != 0){
chg_err(" test do not set ichging , wireless charge start \n");
return;
}
#endif
#endif
switch (chip->charger_type) {
case POWER_SUPPLY_TYPE_UNKNOWN:
return;
case POWER_SUPPLY_TYPE_USB:
current_limit = chip->limits.input_current_usb_ma;
break;
case POWER_SUPPLY_TYPE_USB_DCP:
current_limit = chip->limits.input_current_charger_ma;
break;
case POWER_SUPPLY_TYPE_USB_CDP:
current_limit = chip->limits.input_current_cdp_ma;
break;
default:
return;
}
if ((chip->chg_ctrl_by_lcd) && (chip->led_on)) {
if (!chip->dual_charger_support || (chip->dual_charger_support && chip->charger_volt > 7500)) {
if (chip->led_temp_status == LED_TEMP_STATUS__HIGH) {
if (current_limit > chip->limits.input_current_led_ma_high){
current_limit = chip->limits.input_current_led_ma_high;
}
} else if (chip->led_temp_status == LED_TEMP_STATUS__WARM) {
if (current_limit > chip->limits.input_current_led_ma_warm){
current_limit = chip->limits.input_current_led_ma_warm;
}
} else {
if (current_limit > chip->limits.input_current_led_ma_normal){
current_limit = chip->limits.input_current_led_ma_normal;
}
}
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY]LED STATUS CHANGED, IS ON\n");
}
if ((chip->chg_ctrl_by_camera) && (chip->camera_on)
&& (current_limit > chip->limits.input_current_camera_ma)) {
current_limit = chip->limits.input_current_camera_ma;
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY]CAMERA STATUS CHANGED, IS ON\n");
}
} else if ((chip->chg_ctrl_by_camera) && (chip->camera_on)
&&(current_limit > chip->limits.input_current_camera_ma)) {
current_limit = chip->limits.input_current_camera_ma;
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY]CAMERA STATUS CHANGED, IS ON\n");
}
if ((chip->chg_ctrl_by_calling) && (chip->calling_on)
&& (current_limit > chip->limits.input_current_calling_ma)) {
current_limit = chip->limits.input_current_calling_ma;
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY]calling STATUS CHANGED, IS ON\n");
}
if (chip->chg_ctrl_by_vooc && chip->vbatt_num == 2
&& oplus_vooc_get_fast_chg_type() == CHARGER_SUBTYPE_FASTCHG_VOOC
&& oplus_vooc_get_fastchg_started() == true) {
if(chip->led_on) {
if(chip->vooc_temp_status == VOOC_TEMP_STATUS__HIGH) {
current_limit = chip->limits.input_current_vooc_led_ma_high;
} else if(chip->vooc_temp_status == VOOC_TEMP_STATUS__WARM) {
current_limit = chip->limits.input_current_vooc_led_ma_warm;
} else if(chip->vooc_temp_status == VOOC_TEMP_STATUS__NORMAL) {
current_limit = chip->limits.input_current_vooc_led_ma_normal;
}
} else if (!(chip->chg_ctrl_by_calling && chip->calling_on)) {
if(chip->vooc_temp_status == VOOC_TEMP_STATUS__HIGH) {
current_limit = chip->limits.input_current_vooc_ma_high;
} else if(chip->vooc_temp_status == VOOC_TEMP_STATUS__WARM) {
current_limit = chip->limits.input_current_vooc_ma_warm;
} else if(chip->vooc_temp_status == VOOC_TEMP_STATUS__NORMAL) {
current_limit = chip->limits.input_current_vooc_ma_normal;
}
}
chg_err("chg_ctrl_by_vooc, \
led_on = %d,\
calling_on = %d,\
current_limit[%d], \
chip->vooc_temp_status[%d]\n",
chip->led_on,
chip->calling_on,
current_limit,
chip->vooc_temp_status);
if ( chip->chg_ops->input_current_ctrl_by_vooc_write) {
chip->chg_ops->input_current_ctrl_by_vooc_write(current_limit);
return;
}
}
if (chip->chg_ctrl_by_cool_down && (current_limit > chip->limits.input_current_cool_down_ma)) {
current_limit = chip->limits.input_current_cool_down_ma;
}
charger_xlog_printk(CHG_LOG_CRTI,
" led_on = %d, \
current_limit = %d, \
led_temp_status = %d\n",
chip->led_on,
current_limit,
chip->led_temp_status);
chip->chg_ops->input_current_write(current_limit);
}
static int oplus_chg_get_float_voltage(struct oplus_chg_chip *chip)
{
int flv = chip->limits.temp_normal_vfloat_mv;
switch (chip->tbatt_status) {
case BATTERY_STATUS__INVALID:
case BATTERY_STATUS__REMOVED:
case BATTERY_STATUS__LOW_TEMP:
case BATTERY_STATUS__HIGH_TEMP:
return flv;
case BATTERY_STATUS__COLD_TEMP:
flv = chip->limits.temp_cold_vfloat_mv;
break;
case BATTERY_STATUS__LITTLE_COLD_TEMP:
flv = chip->limits.temp_little_cold_vfloat_mv;
break;
case BATTERY_STATUS__COOL_TEMP:
flv = chip->limits.temp_cool_vfloat_mv;
break;
case BATTERY_STATUS__LITTLE_COOL_TEMP:
flv = chip->limits.temp_little_cool_vfloat_mv;
break;
case BATTERY_STATUS__NORMAL:
flv = chip->limits.temp_normal_vfloat_mv;
break;
case BATTERY_STATUS__WARM_TEMP:
flv = chip->limits.temp_warm_vfloat_mv;
break;
default:
break;
}
if (oplus_short_c_batt_is_prohibit_chg(chip)
&& flv > chip->limits.short_c_bat_vfloat_mv) {
flv = chip->limits.short_c_bat_vfloat_mv;
}
return flv;
}
static void oplus_chg_set_float_voltage(struct oplus_chg_chip *chip)
{
int flv = oplus_chg_get_float_voltage(chip);
if (((!chip->authenticate) ||(!chip->hmac)) && (flv > chip->limits.non_standard_vfloat_mv)) {
flv = chip->limits.non_standard_vfloat_mv;
charger_xlog_printk(CHG_LOG_CRTI,
"no authenticate or no hmac battery, set float voltage = %d\n",
chip->limits.non_standard_vfloat_mv);
}
chip->chg_ops->float_voltage_write(flv * chip->vbatt_num);
chip->limits.vfloat_sw_set = flv;
}
#define VFLOAT_OVER_NUM 2
static void oplus_chg_vfloat_over_check(struct oplus_chg_chip *chip)
{
if (!chip->mmi_chg) {
return;
}
if (chip->charging_state == CHARGING_STATUS_FULL) {
return;
}
if (oplus_vooc_get_allow_reading() == false) {
return;
}
if (chip->check_batt_full_by_sw
&& (chip->limits.sw_vfloat_over_protect_enable == false)) {
return;
}
if (oplus_vooc_get_fastchg_ing() == true) {
return;
}
#ifndef CONFIG_OPLUS_CHARGER_MTK
if (chip->wireless_support && oplus_wpc_get_ffc_charging() == true) {
return;
}
#endif
//if (!((oplus_vooc_get_fastchg_to_normal()== true) || (oplus_vooc_get_fastchg_to_warm() == true))) {
if(chip->limits.sw_vfloat_over_protect_enable) {
if ((chip->batt_volt >= chip->limits.cold_vfloat_over_sw_limit
&& chip->tbatt_status == BATTERY_STATUS__COLD_TEMP)
||(chip->batt_volt >= chip->limits.little_cold_vfloat_over_sw_limit
&& chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP)
||(chip->batt_volt >= chip->limits.cool_vfloat_over_sw_limit
&& chip->tbatt_status == BATTERY_STATUS__COOL_TEMP)
||(chip->batt_volt >= chip->limits.little_cool_vfloat_over_sw_limit
&& chip->tbatt_status == BATTERY_STATUS__LITTLE_COOL_TEMP)
||(chip->batt_volt >= chip->limits.normal_vfloat_over_sw_limit
&& chip->tbatt_status == BATTERY_STATUS__NORMAL)
||(chip->batt_volt >= chip->limits.warm_vfloat_over_sw_limit
&& chip->tbatt_status == BATTERY_STATUS__WARM_TEMP)
||(((!chip->authenticate) ||(!chip->hmac))
&& (chip->batt_volt >= chip->limits.non_standard_vfloat_over_sw_limit))) {
chip->limits.vfloat_over_counts++;
if (chip->limits.vfloat_over_counts > VFLOAT_OVER_NUM) {
chip->limits.vfloat_over_counts = 0;
chip->limits.vfloat_sw_set -= chip->limits.vfloat_step_mv;
chip->chg_ops->float_voltage_write(chip->limits.vfloat_sw_set * chip->vbatt_num);
charger_xlog_printk(CHG_LOG_CRTI,
"bat_volt:%d, \
tbatt:%d, \
sw_vfloat_set:%d\n",
chip->batt_volt,
chip->tbatt_status,
chip->limits.vfloat_sw_set);
}
} else {
chip->limits.vfloat_over_counts = 0;
}
return;
}
}
static void oplus_chg_check_vbatt_higher_than_4180mv(struct oplus_chg_chip *chip)
{
static bool vol_high_pre = false;
static int lower_count = 0, higher_count = 0;
static int tbatt_status_pre = BATTERY_STATUS__NORMAL;
if (!chip->mmi_chg) {
vbatt_higherthan_4180mv = false;
vol_high_pre = false;
lower_count = 0;
higher_count = 0;
return;
}
if (oplus_vooc_get_fastchg_started() == true) {
return;
}
if (tbatt_status_pre != chip->tbatt_status) {
tbatt_status_pre = chip->tbatt_status;
vbatt_higherthan_4180mv = false;
vol_high_pre = false;
lower_count = 0;
higher_count = 0;
}
//if (chip->batt_volt >(chip->vbatt_num * 4180)) {
if (chip->batt_volt > 4180) {
higher_count++;
if (higher_count > 2) {
lower_count = 0;
higher_count = 3;
vbatt_higherthan_4180mv = true;
}
} else if (vbatt_higherthan_4180mv) {
//if (chip->batt_volt >(chip->vbatt_num * 4000)) {
if (chip->batt_volt < 4000) {
lower_count++;
if (lower_count > 2) {
lower_count = 3;
higher_count = 0;
vbatt_higherthan_4180mv = false;
}
}
}
/*chg_err(" tbatt_status:%d,batt_volt:%d,vol_high_pre:%d,vbatt_higherthan_4180mv:%d\n",*/
/*chip->tbatt_status,chip->batt_volt,vol_high_pre,vbatt_higherthan_4180mv);*/
if (vol_high_pre != vbatt_higherthan_4180mv) {
vol_high_pre = vbatt_higherthan_4180mv;
oplus_chg_set_charging_current(chip);
}
}
#define TEMP_FFC_COUNTS 2
static void oplus_chg_check_ffc_temp_status(struct oplus_chg_chip *chip)
{
int batt_temp = chip->temperature;
OPLUS_CHG_FFC_TEMP_STATUS temp_status = chip->ffc_temp_status;
static int high_counts = 0, warm_counts = 0, normal_counts = 0;
static int low_counts = 0;
if (batt_temp >= chip->limits.ffc2_temp_high_decidegc) { /*>=40C*/
//tled_status = FFC_TEMP_STATUS__HIGH;
high_counts ++;
if (high_counts >= TEMP_FFC_COUNTS) {
low_counts = 0;
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
temp_status = FFC_TEMP_STATUS__HIGH;
}
}else if (batt_temp >= chip->limits.ffc2_temp_warm_decidegc) { /*>=35C && < 40*/
//temp_status = FFC_TEMP_STATUS__WARM;
warm_counts ++;
if (warm_counts >= TEMP_FFC_COUNTS) {
low_counts = 0;
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
temp_status = FFC_TEMP_STATUS__WARM;
}
} else if (batt_temp >= chip->limits.ffc2_temp_low_decidegc) { /*>=16C&&<35C*/
//temp_status = FFC_TEMP_STATUS__NORMAL;
normal_counts ++;
if (normal_counts >= TEMP_FFC_COUNTS) {
low_counts = 0;
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
temp_status = FFC_TEMP_STATUS__NORMAL;
}
} else { /*<16C*/
low_counts++;
if (low_counts >= TEMP_FFC_COUNTS) {
low_counts = 0;
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
temp_status = FFC_TEMP_STATUS__LOW;
}
}
if (temp_status != chip->ffc_temp_status) {
chip->ffc_temp_status = temp_status;
}
}
void oplus_chg_turn_on_ffc1(struct oplus_chg_chip *chip)
{
if ((!chip->authenticate) ||(!chip->hmac)) {
return;
}
if (!chip->mmi_chg) {
return;
}
if (oplus_vooc_get_allow_reading() == false) {
return;
}
chip->chg_ops->hardware_init();
if (chip->stop_chg == 0
&& (chip->charger_type == POWER_SUPPLY_TYPE_USB
|| chip->charger_type == POWER_SUPPLY_TYPE_USB_CDP)) {
chip->chg_ops->charger_suspend();
}
if (chip->check_batt_full_by_sw) {
chip->chg_ops->set_charging_term_disable();
}
pr_err("oplus_chg_turn_on_ffc1--------\r\n");
chip->chg_ctrl_by_lcd = false;
chip->fastchg_to_ffc = true;
chip->fastchg_ffc_status = 1;
chip->chg_ctrl_by_vooc = false;
chip->recharge_after_ffc = true;
if (chip->temperature >= chip->limits.ffc2_temp_warm_decidegc) {
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.ff1_warm_fastchg_ma;
chip->limits.temp_little_cool_fastchg_current_ma
= chip->limits.ff1_warm_fastchg_ma;
} else {
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.ff1_normal_fastchg_ma;
chip->limits.temp_little_cool_fastchg_current_ma
= chip->limits.ff1_normal_fastchg_ma;
}
chip->limits.normal_vfloat_sw_limit
= chip->limits.ffc1_normal_vfloat_sw_limit;
chip->limits.temp_normal_vfloat_mv
= chip->limits.ffc1_temp_normal_vfloat_mv;
chip->limits.normal_vfloat_over_sw_limit
= chip->limits.ffc1_normal_vfloat_over_sw_limit;
chip->limits.little_cool_vfloat_sw_limit
= chip->limits.ffc1_normal_vfloat_sw_limit;
chip->limits.temp_little_cool_vfloat_mv
= chip->limits.ffc1_temp_normal_vfloat_mv;
chip->limits.little_cool_vfloat_over_sw_limit
= chip->limits.ffc1_normal_vfloat_over_sw_limit;
oplus_chg_check_tbatt_status(chip);
oplus_chg_set_float_voltage(chip);
oplus_chg_set_charging_current(chip);
oplus_chg_set_input_current_limit(chip);
chip->chg_ops->term_current_set(chip->limits.iterm_ma);
}
void oplus_chg_turn_on_ffc2(struct oplus_chg_chip *chip)
{
if ((!chip->authenticate) ||(!chip->hmac)) {
return;
}
if (!chip->mmi_chg) {
return;
}
if (oplus_vooc_get_allow_reading() == false) {
return;
}
chip->chg_ops->hardware_init();
if (chip->check_batt_full_by_sw) {
chip->chg_ops->set_charging_term_disable();
}
pr_err("oplus_chg_turn_on_ffc2--------\r\n");
chip->chg_ctrl_by_lcd = false;
chip->fastchg_to_ffc = true;
chip->fastchg_ffc_status = 2;
chip->chg_ctrl_by_vooc = false;
chip->recharge_after_ffc = true;
if (chip->temperature >= chip->limits.ffc2_temp_warm_decidegc) {
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.ffc2_warm_fastchg_ma;
chip->limits.temp_little_cool_fastchg_current_ma
= chip->limits.ffc2_warm_fastchg_ma;
} else {
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.ffc2_normal_fastchg_ma;
chip->limits.temp_little_cool_fastchg_current_ma
= chip->limits.ffc2_normal_fastchg_ma;
}
chip->limits.normal_vfloat_sw_limit
= chip->limits.ffc2_normal_vfloat_sw_limit;
chip->limits.temp_normal_vfloat_mv
= chip->limits.ffc2_temp_normal_vfloat_mv;
chip->limits.normal_vfloat_over_sw_limit
= chip->limits.ffc2_normal_vfloat_over_sw_limit;
chip->limits.little_cool_vfloat_sw_limit
= chip->limits.ffc2_normal_vfloat_sw_limit;
chip->limits.temp_little_cool_vfloat_mv
= chip->limits.ffc2_temp_normal_vfloat_mv;
chip->limits.little_cool_vfloat_over_sw_limit
= chip->limits.ffc2_normal_vfloat_over_sw_limit;
oplus_chg_check_tbatt_status(chip);
oplus_chg_set_float_voltage(chip);
oplus_chg_set_charging_current(chip);
oplus_chg_set_input_current_limit(chip);
chip->chg_ops->term_current_set(chip->limits.iterm_ma);
}
void oplus_chg_turn_on_charging(struct oplus_chg_chip *chip)
{
if (!chip->authenticate) {
return;
}
if (!chip->mmi_chg) {
return;
}
if (oplus_vooc_get_allow_reading() == false) {
return;
}
chip->chg_ops->hardware_init();
if (chip->stop_chg == 0
&& (chip->charger_type == POWER_SUPPLY_TYPE_USB
|| chip->charger_type == POWER_SUPPLY_TYPE_USB_CDP)) {
chip->chg_ops->charger_suspend();
}
if (chip->check_batt_full_by_sw) {
chip->chg_ops->set_charging_term_disable();
}
oplus_chg_check_tbatt_status(chip);
oplus_chg_set_float_voltage(chip);
oplus_chg_set_charging_current(chip);
oplus_chg_set_input_current_limit(chip);
chip->chg_ops->term_current_set(chip->limits.iterm_ma);
}
void oplus_chg_turn_off_charging(struct oplus_chg_chip *chip)
{
if (oplus_vooc_get_allow_reading() == false) {
return;
}
switch (chip->tbatt_status) {
case BATTERY_STATUS__INVALID:
case BATTERY_STATUS__REMOVED:
case BATTERY_STATUS__LOW_TEMP:
break;
case BATTERY_STATUS__HIGH_TEMP:
break;
case BATTERY_STATUS__COLD_TEMP:
break;
case BATTERY_STATUS__LITTLE_COLD_TEMP:
case BATTERY_STATUS__COOL_TEMP:
chip->chg_ops->charging_current_write_fast(chip->limits.temp_cold_fastchg_current_ma);
msleep(50);
break;
case BATTERY_STATUS__LITTLE_COOL_TEMP:
case BATTERY_STATUS__NORMAL:
chip->chg_ops->charging_current_write_fast(chip->limits.temp_cool_fastchg_current_ma_high);
msleep(50);
chip->chg_ops->charging_current_write_fast(chip->limits.temp_cold_fastchg_current_ma);
msleep(50);
break;
case BATTERY_STATUS__WARM_TEMP:
chip->chg_ops->charging_current_write_fast(chip->limits.temp_cold_fastchg_current_ma);
msleep(50);
break;
default:
break;
}
chip->chg_ops->charging_disable();
/*charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY] oplus_chg_turn_off_charging !!\n");*/
}
/*
static int oplus_chg_check_suspend_or_disable(struct oplus_chg_chip *chip)
{
if(chip->suspend_after_full) {
if(chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP
|| chip->tbatt_status == BATTERY_STATUS__COOL_TEMP
|| chip->tbatt_status == BATTERY_STATUS__LITTLE_COOL_TEMP
|| chip->tbatt_status == BATTERY_STATUS__NORMAL) {
return CHG_SUSPEND;
} else if(chip->tbatt_status == BATTERY_STATUS__COLD_TEMP) {
return CHG_DISABLE;
} else {
return CHG_NO_SUSPEND_NO_DISABLE;
}
} else {
if(chip->tbatt_status == BATTERY_STATUS__COLD_TEMP
|| chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP) {
return CHG_DISABLE;
} else {
return CHG_NO_SUSPEND_NO_DISABLE;
}
}
}
*/
static int oplus_chg_check_suspend_or_disable(struct oplus_chg_chip *chip)
{
if (chip->suspend_after_full) {
if ((chip->tbatt_status == BATTERY_STATUS__HIGH_TEMP
|| chip->tbatt_status == BATTERY_STATUS__WARM_TEMP) && (chip->batt_volt < 4250)) {
return CHG_DISABLE;
} else {
return CHG_SUSPEND;
}
} else {
return CHG_DISABLE;
}
}
static void oplus_chg_voter_charging_start(struct oplus_chg_chip *chip,
OPLUS_CHG_STOP_VOTER voter)
{
chip->chging_on = true;
chip->stop_voter &= ~(int)voter;
oplus_chg_turn_on_charging(chip);
switch (voter) {
case CHG_STOP_VOTER__FULL:
chip->charging_state = CHARGING_STATUS_CCCV;
if (oplus_vooc_get_allow_reading() == true) {
chip->chg_ops->charger_unsuspend();
chip->chg_ops->charging_enable();
}
break;
case CHG_STOP_VOTER__VCHG_ABNORMAL:
chip->charging_state = CHARGING_STATUS_CCCV;
if (oplus_vooc_get_allow_reading() == true) {
chip->chg_ops->charger_unsuspend();
}
break;
case CHG_STOP_VOTER__BATTTEMP_ABNORMAL:
case CHG_STOP_VOTER__VBAT_TOO_HIGH:
case CHG_STOP_VOTER__MAX_CHGING_TIME:
chip->charging_state = CHARGING_STATUS_CCCV;
break;
default:
break;
}
}
static void oplus_chg_voter_charging_stop(struct oplus_chg_chip *chip,
OPLUS_CHG_STOP_VOTER voter)
{
chip->chging_on = false;
chip->stop_voter |= (int)voter;
switch (voter) {
case CHG_STOP_VOTER__FULL:
chip->charging_state = CHARGING_STATUS_FULL;
if (oplus_vooc_get_allow_reading() == true) {
if (oplus_chg_check_suspend_or_disable(chip) == CHG_SUSPEND) {
chip->chg_ops->charger_suspend();
} else {
oplus_chg_turn_off_charging(chip);
}
}
break;
case CHG_STOP_VOTER__VCHG_ABNORMAL:
chip->charging_state = CHARGING_STATUS_FAIL;
chip->total_time = 0;
if (oplus_vooc_get_allow_reading() == true) {
chip->chg_ops->charger_suspend();
}
oplus_chg_turn_off_charging(chip);
break;
case CHG_STOP_VOTER__BATTTEMP_ABNORMAL:
case CHG_STOP_VOTER__VBAT_TOO_HIGH:
chip->charging_state = CHARGING_STATUS_FAIL;
chip->total_time = 0;
oplus_chg_turn_off_charging(chip);
break;
case CHG_STOP_VOTER__MAX_CHGING_TIME:
chip->charging_state = CHARGING_STATUS_FAIL;
oplus_chg_turn_off_charging(chip);
break;
default:
break;
}
}
#define HYSTERISIS_DECIDEGC 20
#define HYSTERISIS_DECIDEGC_0C 5
#define TBATT_PRE_SHAKE_INVALID 999
static void battery_temp_anti_shake_handle(struct oplus_chg_chip *chip)
{
int tbatt_cur_shake = chip->temperature, low_shake = 0, high_shake = 0;
int low_shake_0c = 0, high_shake_0c = 0;
if (tbatt_cur_shake > chip->tbatt_pre_shake) { /*get warmer*/
low_shake = -HYSTERISIS_DECIDEGC;
high_shake = 0;
low_shake_0c = -HYSTERISIS_DECIDEGC_0C;
high_shake_0c = 0;
} else if (tbatt_cur_shake < chip->tbatt_pre_shake) { /*get cooler*/
low_shake = 0;
high_shake = HYSTERISIS_DECIDEGC;
low_shake_0c = 0;
high_shake_0c = HYSTERISIS_DECIDEGC_0C;
}
if (chip->tbatt_status == BATTERY_STATUS__HIGH_TEMP) { /*>53C*/
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound; /*-3C*/
chip->limits.little_cold_bat_decidegc = chip->anti_shake_bound.little_cold_bound; /*0C*/
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound; /*5C*/
chip->limits.little_cool_bat_decidegc = chip->anti_shake_bound.little_cool_bound; /*12C*/
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound; /*16C*/
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound; /*45C*/
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound + low_shake; /*53C*/
} else if (chip->tbatt_status == BATTERY_STATUS__LOW_TEMP) { /*<-3C*/
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound + high_shake;
chip->limits.little_cold_bat_decidegc = chip->anti_shake_bound.little_cold_bound;
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound;
chip->limits.little_cool_bat_decidegc = chip->anti_shake_bound.little_cool_bound;
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound;
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound;
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound;
} else if (chip->tbatt_status == BATTERY_STATUS__COLD_TEMP) { /*-3C~0C*/
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound + low_shake;
chip->limits.little_cold_bat_decidegc = chip->anti_shake_bound.little_cold_bound + high_shake_0c;
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound;
chip->limits.little_cool_bat_decidegc = chip->anti_shake_bound.little_cool_bound;
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound;
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound;
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound;
} else if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP) { /*0C-5C*/
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound;
chip->limits.little_cold_bat_decidegc = chip->anti_shake_bound.little_cold_bound + low_shake_0c;
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound + high_shake;
chip->limits.little_cool_bat_decidegc = chip->anti_shake_bound.little_cool_bound;
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound;
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound;
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound;
} else if (chip->tbatt_status == BATTERY_STATUS__COOL_TEMP) { /*5C~12C*/
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound;
chip->limits.little_cold_bat_decidegc = chip->anti_shake_bound.little_cold_bound;
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound + low_shake;
chip->limits.little_cool_bat_decidegc = chip->anti_shake_bound.little_cool_bound + high_shake;
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound;
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound;
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound;
} else if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COOL_TEMP) { /*12C~16C*/
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound;
chip->limits.little_cold_bat_decidegc = chip->anti_shake_bound.little_cold_bound;
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound;
chip->limits.little_cool_bat_decidegc = chip->anti_shake_bound.little_cool_bound + low_shake;
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound + high_shake;
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound;
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound;
} else if (chip->tbatt_status == BATTERY_STATUS__NORMAL) { /*16C~45C*/
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound;
chip->limits.little_cold_bat_decidegc = chip->anti_shake_bound.little_cold_bound;
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound;
chip->limits.little_cool_bat_decidegc = chip->anti_shake_bound.little_cool_bound;
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound;
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound;
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound;
} else if (chip->tbatt_status == BATTERY_STATUS__WARM_TEMP) { /*45C~53C*/
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound;
chip->limits.little_cold_bat_decidegc = chip->anti_shake_bound.little_cold_bound;
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound;
chip->limits.little_cool_bat_decidegc = chip->anti_shake_bound.little_cool_bound;
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound;
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound + low_shake;
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound + high_shake;
} else { /*BATTERY_STATUS__REMOVED <-19C*/
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound;
chip->limits.little_cold_bat_decidegc = chip->anti_shake_bound.little_cold_bound;
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound;
chip->limits.little_cool_bat_decidegc = chip->anti_shake_bound.little_cool_bound;
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound;
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound;
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound;
}
chip->tbatt_pre_shake = tbatt_cur_shake;
}
#define TEMP_CNT 1
static bool oplus_chg_check_tbatt_is_good(struct oplus_chg_chip *chip)
{
static bool ret = true;
static int temp_counts = 0;
int batt_temp = chip->temperature;
OPLUS_CHG_TBATT_STATUS tbatt_status = chip->tbatt_status;
if (batt_temp > chip->limits.hot_bat_decidegc || batt_temp < chip->limits.cold_bat_decidegc) {
temp_counts++;
if (temp_counts >= TEMP_CNT) {
temp_counts = 0;
ret = false;
if (batt_temp <= chip->limits.removed_bat_decidegc) {
tbatt_status = BATTERY_STATUS__REMOVED;
} else if (batt_temp > chip->limits.hot_bat_decidegc) {
tbatt_status = BATTERY_STATUS__HIGH_TEMP;
} else {
tbatt_status = BATTERY_STATUS__LOW_TEMP;
}
}
} else {
temp_counts = 0;
ret = true;
if (batt_temp >= chip->limits.warm_bat_decidegc) { /*45C*/
tbatt_status = BATTERY_STATUS__WARM_TEMP;
} else if (batt_temp >= chip->limits.normal_bat_decidegc) { /*16C*/
tbatt_status = BATTERY_STATUS__NORMAL;
} else if (batt_temp >= chip->limits.little_cool_bat_decidegc) { /*12C*/
tbatt_status = BATTERY_STATUS__LITTLE_COOL_TEMP;
} else if (batt_temp >= chip->limits.cool_bat_decidegc) { /*5C*/
tbatt_status = BATTERY_STATUS__COOL_TEMP;
} else if (batt_temp >= chip->limits.little_cold_bat_decidegc) { /*0C*/
tbatt_status = BATTERY_STATUS__LITTLE_COLD_TEMP;
} else if (batt_temp >= chip->limits.cold_bat_decidegc) { /*-3C*/
tbatt_status = BATTERY_STATUS__COLD_TEMP;
} else {
tbatt_status = BATTERY_STATUS__COLD_TEMP;
}
}
if (tbatt_status == BATTERY_STATUS__REMOVED) {
chip->batt_exist = false;
} else {
chip->batt_exist = true;
}
if (chip->tbatt_pre_shake == TBATT_PRE_SHAKE_INVALID) {
chip->tbatt_pre_shake = batt_temp;
}
if (tbatt_status != chip->tbatt_status) {
if (chip->tbatt_status == BATTERY_STATUS__WARM_TEMP
|| chip->tbatt_status == BATTERY_STATUS__COLD_TEMP) {
if (chip->soc != 100 && chip->batt_full == true
&& chip->charging_state == CHARGING_STATUS_FULL) {
chip->batt_full = false;
chip->tbatt_when_full = 200;
oplus_chg_voter_charging_start(chip, CHG_STOP_VOTER__FULL);
}
}
chip->tbatt_status = tbatt_status;
vbatt_higherthan_4180mv = false;
if (oplus_vooc_get_allow_reading() == true) {
oplus_chg_set_float_voltage(chip);
oplus_chg_set_charging_current(chip);
}
battery_temp_anti_shake_handle(chip);
}
return ret;
}
static void oplus_chg_check_tbatt_status(struct oplus_chg_chip *chip)
{
int batt_temp = chip->temperature;
OPLUS_CHG_TBATT_STATUS tbatt_status = chip->tbatt_status;
if (batt_temp > chip->limits.hot_bat_decidegc) { /*53C*/
tbatt_status = BATTERY_STATUS__HIGH_TEMP;
} else if (batt_temp >= chip->limits.warm_bat_decidegc) { /*45C*/
tbatt_status = BATTERY_STATUS__WARM_TEMP;
} else if (batt_temp >= chip->limits.normal_bat_decidegc) { /*16C*/
tbatt_status = BATTERY_STATUS__NORMAL;
} else if (batt_temp >= chip->limits.little_cool_bat_decidegc) { /*12C*/
tbatt_status = BATTERY_STATUS__LITTLE_COOL_TEMP;
} else if (batt_temp >= chip->limits.cool_bat_decidegc) { /*5C*/
tbatt_status = BATTERY_STATUS__COOL_TEMP;
} else if (batt_temp >= chip->limits.little_cold_bat_decidegc) { /*0C*/
tbatt_status = BATTERY_STATUS__LITTLE_COLD_TEMP;
} else if (batt_temp >= chip->limits.cold_bat_decidegc) { /*-3C*/
tbatt_status = BATTERY_STATUS__COLD_TEMP;
} else if (batt_temp > chip->limits.removed_bat_decidegc) { /*-20C*/
tbatt_status = BATTERY_STATUS__LOW_TEMP;
} else {
tbatt_status = BATTERY_STATUS__REMOVED;
}
if (tbatt_status == BATTERY_STATUS__REMOVED) {
chip->batt_exist = false;
} else {
chip->batt_exist = true;
}
chip->tbatt_status = tbatt_status;
}
static void battery_temp_normal_anti_shake_handle(struct oplus_chg_chip *chip)
{
int tbatt_normal_cur_shake = chip->temperature, low_shake = 0, high_shake = 0;
if (tbatt_normal_cur_shake > chip->tbatt_normal_pre_shake) { /*get warmer*/
low_shake = -HYSTERISIS_DECIDEGC;
high_shake = 0;
} else if (tbatt_normal_cur_shake < chip->tbatt_normal_pre_shake) { /*get cooler*/
low_shake = 0;
high_shake = HYSTERISIS_DECIDEGC;
}
if (chip->tbatt_normal_status == BATTERY_STATUS__NORMAL_PHASE1) {
chip->limits.normal_phase1_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase1_bound;
chip->limits.normal_phase2_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase2_bound + high_shake;
chip->limits.normal_phase3_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase3_bound;
chip->limits.normal_phase4_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase4_bound;
chip->limits.normal_phase5_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase5_bound;
chip->limits.normal_phase6_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase6_bound;
} else if (chip->tbatt_normal_status == BATTERY_STATUS__NORMAL_PHASE2) {
chip->limits.normal_phase1_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase1_bound;
chip->limits.normal_phase2_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase2_bound + low_shake;
chip->limits.normal_phase3_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase3_bound + high_shake;
chip->limits.normal_phase4_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase4_bound;
chip->limits.normal_phase5_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase5_bound;
chip->limits.normal_phase6_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase6_bound;
} else if (chip->tbatt_normal_status == BATTERY_STATUS__NORMAL_PHASE3) {
chip->limits.normal_phase1_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase1_bound;
chip->limits.normal_phase2_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase2_bound;
chip->limits.normal_phase3_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase3_bound + low_shake;
chip->limits.normal_phase4_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase4_bound + high_shake;
chip->limits.normal_phase5_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase5_bound;
chip->limits.normal_phase6_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase6_bound;
} else if (chip->tbatt_normal_status == BATTERY_STATUS__NORMAL_PHASE4) {
chip->limits.normal_phase1_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase1_bound;
chip->limits.normal_phase2_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase2_bound;
chip->limits.normal_phase3_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase3_bound;
chip->limits.normal_phase4_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase4_bound + low_shake;
chip->limits.normal_phase5_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase5_bound + high_shake;
chip->limits.normal_phase6_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase6_bound;
} else if (chip->tbatt_normal_status == BATTERY_STATUS__NORMAL_PHASE5) {
chip->limits.normal_phase1_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase1_bound;
chip->limits.normal_phase2_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase2_bound;
chip->limits.normal_phase3_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase3_bound;
chip->limits.normal_phase4_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase4_bound;
chip->limits.normal_phase5_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase5_bound + low_shake;
chip->limits.normal_phase6_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase6_bound + high_shake;
} else if (chip->tbatt_normal_status == BATTERY_STATUS__NORMAL_PHASE6) {
chip->limits.normal_phase1_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase1_bound;
chip->limits.normal_phase2_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase2_bound;
chip->limits.normal_phase3_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase3_bound;
chip->limits.normal_phase4_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase4_bound;
chip->limits.normal_phase5_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase5_bound;
chip->limits.normal_phase6_bat_decidegc = chip->tbatt_normal_anti_shake_bound.phase6_bound + low_shake;
} else {
/*do nothing*/
}
chip->tbatt_normal_pre_shake = tbatt_normal_cur_shake;
}
static void oplus_chg_check_tbatt_normal_status(struct oplus_chg_chip *chip)
{
int batt_temp = chip->temperature;
OPLUS_CHG_TBATT_NORMAL_STATUS tbatt_normal_status = chip->tbatt_normal_status;
if (chip->tbatt_status == BATTERY_STATUS__NORMAL) {
if (batt_temp >= chip->limits.normal_phase6_bat_decidegc) {
tbatt_normal_status = BATTERY_STATUS__NORMAL_PHASE6;
} else if (batt_temp >= chip->limits.normal_phase5_bat_decidegc) {
tbatt_normal_status = BATTERY_STATUS__NORMAL_PHASE5;
} else if (batt_temp >= chip->limits.normal_phase4_bat_decidegc) {
tbatt_normal_status = BATTERY_STATUS__NORMAL_PHASE4;
} else if (batt_temp >= chip->limits.normal_phase3_bat_decidegc) {
tbatt_normal_status = BATTERY_STATUS__NORMAL_PHASE3;
} else if (batt_temp >= chip->limits.normal_phase2_bat_decidegc) {
tbatt_normal_status = BATTERY_STATUS__NORMAL_PHASE2;
} else if (batt_temp >= chip->limits.normal_phase1_bat_decidegc) {
tbatt_normal_status = BATTERY_STATUS__NORMAL_PHASE1;
} else {
/*do nothing*/
}
}
if (chip->tbatt_normal_pre_shake == TBATT_PRE_SHAKE_INVALID) {
chip->tbatt_pre_shake = batt_temp;
}
if (chip->tbatt_normal_status != tbatt_normal_status) {
chip->tbatt_normal_status = tbatt_normal_status;
if (oplus_vooc_get_allow_reading() == true) {
oplus_chg_set_float_voltage(chip);
oplus_chg_set_charging_current(chip);
}
battery_temp_normal_anti_shake_handle(chip);
chg_debug("tbatt_normal_status status change, [%d %d %d %d %d %d %d]\n", chip->tbatt_normal_status,
chip->limits.normal_phase1_bat_decidegc, chip->limits.normal_phase2_bat_decidegc,
chip->limits.normal_phase3_bat_decidegc, chip->limits.normal_phase4_bat_decidegc,
chip->limits.normal_phase5_bat_decidegc, chip->limits.normal_phase6_bat_decidegc);
}
}
#define VCHG_CNT 2
static bool oplus_chg_check_vchg_is_good(struct oplus_chg_chip *chip)
{
static bool ret = true;
static int vchg_counts = 0;
int chg_volt = chip->charger_volt;
OPLUS_CHG_VCHG_STATUS vchg_status = chip->vchg_status;
#ifndef CONFIG_OPLUS_CHARGER_MTK
#ifndef WPC_NEW_INTERFACE
if (chip->wireless_support && oplus_wireless_charge_start() == true) {
chg_err(" test wireless fastchg charge start\n");
return true;
}
#else
if (oplus_wpc_get_status() != 0){
chg_err(" test do not set ichging , wireless charge start \n");
return;
}
#endif
#endif
if (oplus_vooc_get_adapter_update_status() == ADAPTER_FW_NEED_UPDATE) {
return true;
}
if (oplus_vooc_get_fastchg_started() == true) {
return true;
}
if (chg_volt > chip->limits.charger_hv_thr) {
vchg_counts++;
if (vchg_counts >= VCHG_CNT) {
vchg_counts = 0;
ret = false;
vchg_status = CHARGER_STATUS__VOL_HIGH;
}
} else if (chg_volt <= chip->limits.charger_recv_thr) {
vchg_counts = 0;
ret = true;
vchg_status = CHARGER_STATUS__GOOD;
}
if (vchg_status != chip->vchg_status) {
chip->vchg_status = vchg_status;
}
return ret;
}
#define VBAT_CNT 1
static bool oplus_chg_check_vbatt_is_good(struct oplus_chg_chip *chip)
{
static bool ret = true;
static int vbat_counts = 0;
int batt_volt = chip->batt_volt;
if (batt_volt >= chip->limits.vbatt_hv_thr) {
vbat_counts++;
if (vbat_counts >= VBAT_CNT) {
vbat_counts = 0;
ret = false;
chip->vbatt_over = true;
}
} else {
vbat_counts = 0;
ret = true;
chip->vbatt_over = false;
}
return ret;
}
static bool oplus_chg_check_time_is_good(struct oplus_chg_chip *chip)
{
#ifdef SELL_MODE
/* Qiao.Hu@BSP.BaseDrv.CHG.Basic, 2017/10/26, delete over_time for sell_mode */
chip->chging_over_time = false;
printk("oplus_chg_check_time_is_good_sell_mode\n");
return true;
#endif //SELL_MODE
if (chip->limits.max_chg_time_sec < 0) {
chip->chging_over_time = false;
return true;
}
if (chip->total_time >= chip->limits.max_chg_time_sec) {
chip->total_time = chip->limits.max_chg_time_sec;
chip->chging_over_time = true;
return false;
} else {
chip->chging_over_time = false;
return true;
}
}
#ifdef CONFIG_FB
#ifdef CONFIG_DRM_MSM
static int fb_notifier_callback(struct notifier_block *nb,
unsigned long event, void *data)
{
int blank;
struct msm_drm_notifier *evdata = data;
if (!g_charger_chip) {
return 0;
}
if (!evdata || (evdata->id != 0)){
return 0;
}
if (event == MSM_DRM_EARLY_EVENT_BLANK) {
blank = *(int *)(evdata->data);
if (blank == MSM_DRM_BLANK_UNBLANK) {
g_charger_chip->led_on = true;
g_charger_chip->led_on_change = true;
} else if (blank == MSM_DRM_BLANK_POWERDOWN) {
g_charger_chip->led_on = false;
g_charger_chip->led_on_change = true;
} else {
pr_err("%s: receives wrong data EARLY_BLANK:%d\n", __func__, blank);
}
}
return 0;
}
#else
static int fb_notifier_callback(struct notifier_block *nb,
unsigned long event, void *data)
{
int blank;
struct fb_event *evdata = data;
if (!g_charger_chip) {
return 0;
}
if (evdata && evdata->data) {
if (event == FB_EVENT_BLANK) {
blank = *(int *)evdata->data;
if (blank == FB_BLANK_UNBLANK) {
g_charger_chip->led_on = true;
g_charger_chip->led_on_change = true;
} else if (blank == FB_BLANK_POWERDOWN) {
g_charger_chip->led_on = false;
g_charger_chip->led_on_change = true;
}
}
}
return 0;
}
#endif /* CONFIG_DRM_MSM */
void oplus_chg_set_allow_switch_to_fastchg(bool allow)
{
charger_xlog_printk(CHG_LOG_CRTI, " allow = %d\n", allow);
if (!g_charger_chip) {
return;
} else {
g_charger_chip->allow_swtich_to_fastchg = allow;
}
}
void oplus_chg_set_led_status(bool val)
{
/*Do nothing*/
}
EXPORT_SYMBOL(oplus_chg_set_led_status);
#else
void oplus_chg_set_led_status(bool val)
{
charger_xlog_printk(CHG_LOG_CRTI, " val = %d\n", val);
if (!g_charger_chip) {
return;
} else {
g_charger_chip->led_on = val;
g_charger_chip->led_on_change = true;
}
}
EXPORT_SYMBOL(oplus_chg_set_led_status);
#endif
void oplus_chg_set_camera_status(bool val)
{
if (!g_charger_chip) {
return;
} else {
g_charger_chip->camera_on = val;
}
}
EXPORT_SYMBOL(oplus_chg_set_camera_status);
#define TLED_CHANGE_COUNTS 4
#define TLED_HYSTERISIS_DECIDEGC 10
static void oplus_chg_check_tled_status(struct oplus_chg_chip *chip)
{
OPLUS_CHG_TLED_STATUS tled_status = chip->led_temp_status;
static int high_counts = 0, warm_counts = 0, normal_counts = 0;
if (chip->temperature > chip->limits.led_high_bat_decidegc_antishake) { /* >37C */
high_counts ++;
if (high_counts >= TLED_CHANGE_COUNTS) {
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
tled_status = LED_TEMP_STATUS__HIGH;
}
} else if (chip->temperature > chip->limits.led_warm_bat_decidegc_antishake) { /* >35C && <= 37 */
warm_counts ++;
if (warm_counts >= TLED_CHANGE_COUNTS) {
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
tled_status = LED_TEMP_STATUS__WARM;
}
} else {
normal_counts ++;
if (normal_counts >= TLED_CHANGE_COUNTS) {
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
tled_status = LED_TEMP_STATUS__NORMAL;
}
}
if (tled_status != chip->led_temp_status) {
chip->limits.led_warm_bat_decidegc_antishake
= chip->limits.led_warm_bat_decidegc;
chip->limits.led_high_bat_decidegc_antishake
= chip->limits.led_high_bat_decidegc;
if (tled_status > chip->led_temp_status
&& tled_status == LED_TEMP_STATUS__WARM){
chip->limits.led_warm_bat_decidegc_antishake
= chip->limits.led_warm_bat_decidegc - TLED_HYSTERISIS_DECIDEGC;
} else if (tled_status > chip->led_temp_status
&& tled_status == LED_TEMP_STATUS__HIGH){
chip->limits.led_high_bat_decidegc_antishake
= chip->limits.led_high_bat_decidegc - TLED_HYSTERISIS_DECIDEGC;
} else if (tled_status < chip->led_temp_status
&& tled_status == LED_TEMP_STATUS__NORMAL){
chip->limits.led_warm_bat_decidegc_antishake
= chip->limits.led_warm_bat_decidegc + TLED_HYSTERISIS_DECIDEGC;
} else if (tled_status < chip->led_temp_status
&& tled_status == LED_TEMP_STATUS__WARM){
chip->limits.led_high_bat_decidegc_antishake
= chip->limits.led_high_bat_decidegc + TLED_HYSTERISIS_DECIDEGC;
}
chg_debug("tled status change, [%d %d %d %d]\n",
tled_status,
chip->led_temp_status,
chip->limits.led_warm_bat_decidegc_antishake,
chip->limits.led_high_bat_decidegc_antishake);
chip->led_temp_change = true;
chip->led_temp_status = tled_status;
}
}
static void oplus_chg_check_led_on_ichging(struct oplus_chg_chip *chip)
{
if (chip->led_on_change || (chip->led_on && chip->led_temp_change)) {
chip->led_on_change = false;
chip->led_temp_change = false;
if (chip->chg_ctrl_by_vooc && chip->vbatt_num == 2) {
if (oplus_vooc_get_fastchg_started() == true
&& oplus_vooc_get_fast_chg_type()
!= CHARGER_SUBTYPE_FASTCHG_VOOC) {
return;
}
if (oplus_vooc_get_allow_reading() == true
|| oplus_vooc_get_fast_chg_type()
== CHARGER_SUBTYPE_FASTCHG_VOOC) {
oplus_chg_set_charging_current(chip);
oplus_chg_set_input_current_limit(chip);
}
} else {
if (oplus_vooc_get_fastchg_started() == true) {
return;
}
if (oplus_vooc_get_allow_reading() == true) {
if (chip->dual_charger_support) {
chip->slave_charger_enable = false;
}
oplus_chg_set_charging_current(chip);
oplus_chg_set_input_current_limit(chip);
}
}
}
}
#define TVOOC_COUNTS 2
#define TVOOC_HYSTERISIS_DECIDEGC 10
static void oplus_chg_check_vooc_temp_status(struct oplus_chg_chip *chip)
{
int batt_temp = chip->temperature;
OPLUS_CHG_TBAT_VOOC_STATUS tbat_vooc_status = chip->vooc_temp_status;
static int high_counts = 0, warm_counts = 0, normal_counts = 0;
static bool vooc_first_set_input_current_flag = false;
if (chip->vbatt_num != 2
|| oplus_vooc_get_fast_chg_type() != CHARGER_SUBTYPE_FASTCHG_VOOC
|| oplus_vooc_get_fastchg_started() == false) {
vooc_first_set_input_current_flag = false;
return;
}
if (batt_temp > chip->limits.vooc_high_bat_decidegc) { /*>45C*/
if (oplus_vooc_get_fastchg_started() == true) {
chg_err("tbatt > 45, quick out vooc");
oplus_chg_set_chargerid_switch_val(0);
oplus_vooc_switch_mode(NORMAL_CHARGER_MODE);
}
} else if (batt_temp > chip->limits.vooc_warm_bat_decidegc_antishake) { /*>38C && <= 45*/
high_counts ++;
if(high_counts >= TVOOC_COUNTS)
{
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
tbat_vooc_status = VOOC_TEMP_STATUS__HIGH;
}
} else if (batt_temp >= chip->limits.vooc_normal_bat_decidegc_antishake) { /*>34C && <= 38*/
warm_counts ++;
if (warm_counts >= TVOOC_COUNTS)
{
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
tbat_vooc_status = VOOC_TEMP_STATUS__WARM;
}
} else { // < 34
normal_counts ++;
if (normal_counts >= TVOOC_COUNTS)
{
high_counts = 0;
warm_counts = 0;
normal_counts = 0;
tbat_vooc_status = VOOC_TEMP_STATUS__NORMAL;
}
}
chg_err("tbat_vooc_status[%d],chip->vooc_temp_status[%d] ",
tbat_vooc_status, chip->vooc_temp_status);
if (vooc_first_set_input_current_flag == false) {
chip->limits.temp_little_cool_fastchg_current_ma
= chip->limits.charger_current_vooc_ma_normal;
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.charger_current_vooc_ma_normal;
oplus_chg_set_charging_current(chip);
chg_err("set charger current ctrl by vooc[%d]\n",
chip->limits.temp_little_cool_fastchg_current_ma);
}
if (tbat_vooc_status != chip->vooc_temp_status
|| vooc_first_set_input_current_flag == false) {
chip->limits.vooc_warm_bat_decidegc_antishake
= chip->limits.vooc_warm_bat_decidegc;
chip->limits.vooc_normal_bat_decidegc_antishake
= chip->limits.vooc_normal_bat_decidegc;
if (tbat_vooc_status > chip->vooc_temp_status
&& tbat_vooc_status == VOOC_TEMP_STATUS__WARM) {
chip->limits.vooc_normal_bat_decidegc_antishake
= chip->limits.vooc_normal_bat_decidegc - TVOOC_HYSTERISIS_DECIDEGC;
} else if (tbat_vooc_status > chip->vooc_temp_status
&& tbat_vooc_status == VOOC_TEMP_STATUS__HIGH) {
chip->limits.vooc_warm_bat_decidegc_antishake
= chip->limits.vooc_warm_bat_decidegc - TVOOC_HYSTERISIS_DECIDEGC;
} else if (tbat_vooc_status < chip->vooc_temp_status
&& tbat_vooc_status == VOOC_TEMP_STATUS__NORMAL) {
chip->limits.vooc_normal_bat_decidegc_antishake
= chip->limits.vooc_normal_bat_decidegc + TVOOC_HYSTERISIS_DECIDEGC;
} else if (tbat_vooc_status < chip->vooc_temp_status
&& tbat_vooc_status == VOOC_TEMP_STATUS__WARM) {
chip->limits.vooc_warm_bat_decidegc_antishake
= chip->limits.vooc_warm_bat_decidegc + TVOOC_HYSTERISIS_DECIDEGC;
}
chg_debug("tled status change, [%d %d %d %d]\n",
tbat_vooc_status, chip->vooc_temp_status,
chip->limits.vooc_warm_bat_decidegc_antishake,
chip->limits.vooc_normal_bat_decidegc_antishake);
vooc_first_set_input_current_flag = true;
chip->vooc_temp_change = true;
chip->vooc_temp_status = tbat_vooc_status;
}
}
static void oplus_chg_check_vooc_ichging(struct oplus_chg_chip *chip)
{
if (chip->vbatt_num == 2 && chip->vooc_temp_change) {
chip->vooc_temp_change = false;
if (oplus_vooc_get_fast_chg_type() == CHARGER_SUBTYPE_FASTCHG_VOOC) {
oplus_chg_set_input_current_limit(chip);
}
}
}
static void oplus_chg_check_cool_down_ichging(struct oplus_chg_chip *chip)
{
chip->cool_down_done = false;
if (oplus_vooc_get_allow_reading() == true) {
if (chip->dual_charger_support) {
chip->slave_charger_enable = false;
oplus_chg_set_charging_current(chip);
}
oplus_chg_set_input_current_limit(chip);
}
}
static void oplus_chg_check_camera_on_ichging(struct oplus_chg_chip *chip)
{
static bool camera_pre = false;
if (chip->camera_on != camera_pre) {
camera_pre = chip->camera_on;
if (oplus_vooc_get_fastchg_started() == true) {
return;
}
if (oplus_vooc_get_allow_reading() == true) {
if (chip->dual_charger_support) {
chip->slave_charger_enable = false;
oplus_chg_set_charging_current(chip);
}
oplus_chg_set_input_current_limit(chip);
}
}
}
static void oplus_chg_check_calling_on_ichging(struct oplus_chg_chip *chip)
{
static bool calling_pre = false;
if (chip->calling_on != calling_pre) {
calling_pre = chip->calling_on;
if (oplus_vooc_get_fastchg_started() == true) {
return;
}
if (oplus_vooc_get_allow_reading() == true) {
if (chip->dual_charger_support) {
chip->slave_charger_enable = false;
oplus_chg_set_charging_current(chip);
}
oplus_chg_set_input_current_limit(chip);
}
}
}
static void oplus_chg_battery_authenticate_check(struct oplus_chg_chip *chip)
{
static bool charger_exist_pre = false;
if (charger_exist_pre ^ chip->charger_exist) {
charger_exist_pre = chip->charger_exist;
if (chip->charger_exist && !chip->authenticate) {
chip->authenticate = oplus_gauge_get_batt_authenticate();
}
}
}
void oplus_chg_variables_reset(struct oplus_chg_chip *chip, bool in)
{
if (in) {
chip->charger_exist = true;
chip->chging_on = true;
chip->slave_charger_enable = false;
} else {
if(!oplus_chg_show_vooc_logo_ornot()) {
if(chip->decimal_control) {
cancel_delayed_work_sync(&g_charger_chip->ui_soc_decimal_work);
chip->last_decimal_ui_soc = (chip->ui_soc_integer + chip->ui_soc_decimal);
oplus_chg_ui_soc_decimal_deinit();
pr_err("[oplus_chg_variables_reset]cancel last_decimal_ui_soc:%d", chip->last_decimal_ui_soc);
}
chip->calculate_decimal_time = 0;
}
chip->allow_swtich_to_fastchg = 1;
chip->charger_exist = false;
chip->chging_on = false;
chip->charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
chip->real_charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
vbatt_higherthan_4180mv = false;
suspend_charger = false;
chip->pd_svooc = false;
}
chip->limits.vbatt_pdqc_to_9v_thr = oplus_get_vbatt_pdqc_to_9v_thr();
chip->sw_full_count = 0;
chip->sw_full = false;
chip->hw_full_by_sw = false;
/*chip->charger_volt = 5000;*/
chip->vchg_status = CHARGER_STATUS__GOOD;
chip->batt_full = false;
chip->tbatt_when_full = 200;
chip->recharge_after_ffc = false;
chip->tbatt_status = BATTERY_STATUS__NORMAL;
chip->tbatt_pre_shake = TBATT_PRE_SHAKE_INVALID;
chip->tbatt_normal_status = BATTERY_STATUS__NORMAL_PHASE1;
chip->tbatt_normal_pre_shake = TBATT_PRE_SHAKE_INVALID;
chip->vbatt_over = 0;
chip->total_time = 0;
chip->chging_over_time = 0;
chip->in_rechging = 0;
/*chip->batt_volt = 0;*/
/*chip->temperature = 0;*/
chip->stop_voter = 0x00;
chip->charging_state = CHARGING_STATUS_CCCV;
#ifndef SELL_MODE
/* Qiao.Hu@BSP.BaseDrv.CHG.Basic, 2017/12/12, delete for sell_mode */
if(chip->mmi_fastchg == 0){
chip->mmi_chg = 0;
} else {
chip->mmi_chg = 1;
}
#endif //SELL_MODE
chip->unwakelock_chg = 0;
chip->notify_code = 0;
chip->notify_flag = 0;
if (!((chip->charger_type == POWER_SUPPLY_TYPE_USB_DCP)
|| (oplus_vooc_get_fastchg_started() == true)
|| (oplus_vooc_get_fastchg_to_warm() == true)
|| (oplus_vooc_get_fastchg_dummy_started() == true)
|| (oplus_vooc_get_adapter_update_status() == ADAPTER_FW_NEED_UPDATE)
|| (oplus_vooc_get_btb_temp_over() == true))) {
chip->cool_down = 0;
chip->cool_down_done = false;
}
chip->cool_down_force_5v = false;
chip->limits.cold_bat_decidegc = chip->anti_shake_bound.cold_bound;
chip->limits.little_cold_bat_decidegc
= chip->anti_shake_bound.little_cold_bound;
chip->limits.cool_bat_decidegc = chip->anti_shake_bound.cool_bound;
chip->limits.little_cool_bat_decidegc
= chip->anti_shake_bound.little_cool_bound;
chip->limits.normal_bat_decidegc = chip->anti_shake_bound.normal_bound;
chip->limits.warm_bat_decidegc = chip->anti_shake_bound.warm_bound;
chip->limits.hot_bat_decidegc = chip->anti_shake_bound.hot_bound;
chip->limits.normal_phase1_bat_decidegc
= chip->tbatt_normal_anti_shake_bound.phase1_bound;
chip->limits.normal_phase2_bat_decidegc
= chip->tbatt_normal_anti_shake_bound.phase2_bound;
chip->limits.normal_phase3_bat_decidegc
= chip->tbatt_normal_anti_shake_bound.phase3_bound;
chip->limits.normal_phase4_bat_decidegc
= chip->tbatt_normal_anti_shake_bound.phase4_bound;
chip->limits.normal_phase5_bat_decidegc
= chip->tbatt_normal_anti_shake_bound.phase5_bound;
chip->limits.normal_phase6_bat_decidegc
= chip->tbatt_normal_anti_shake_bound.phase6_bound;
chip->limits.vfloat_over_counts = 0;
chip->limits.led_warm_bat_decidegc_antishake
= chip->limits.led_warm_bat_decidegc;
chip->limits.led_high_bat_decidegc_antishake
= chip->limits.led_high_bat_decidegc;
chip->led_temp_change = false;
chip->limits.vooc_warm_bat_decidegc_antishake
= chip->limits.vooc_warm_bat_decidegc;
chip->limits.vooc_normal_bat_decidegc_antishake
= chip->limits.vooc_normal_bat_decidegc;
chip->vooc_temp_change = false;
if (chip->temperature > chip->limits.led_high_bat_decidegc) {
chip->led_temp_status = LED_TEMP_STATUS__HIGH;
}else if (chip->temperature > chip->limits.led_warm_bat_decidegc) {
chip->led_temp_status = LED_TEMP_STATUS__WARM;
}else{
chip->led_temp_status = LED_TEMP_STATUS__NORMAL;
}
chip->dod0_counts = 0;
chip->fastchg_to_ffc = false;
chip->fastchg_ffc_status = 0;
chip->chg_ctrl_by_lcd = chip->chg_ctrl_by_lcd_default;
chip->chg_ctrl_by_vooc = chip->chg_ctrl_by_vooc_default;
chip->ffc_temp_status = FFC_TEMP_STATUS__NORMAL;
chip->vooc_temp_status = VOOC_TEMP_STATUS__NORMAL;
chip->limits.iterm_ma = chip->limits.default_iterm_ma;
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.default_temp_normal_fastchg_current_ma;
chip->limits.normal_vfloat_sw_limit
= chip->limits.default_normal_vfloat_sw_limit;
chip->limits.temp_normal_vfloat_mv
= chip->limits.default_temp_normal_vfloat_mv;
chip->limits.normal_vfloat_over_sw_limit
= chip->limits.default_normal_vfloat_over_sw_limit;
chip->limits.temp_little_cool_fastchg_current_ma
= chip->limits.default_temp_little_cool_fastchg_current_ma;
chip->limits.little_cool_vfloat_sw_limit
= chip->limits.default_little_cool_vfloat_sw_limit;
chip->limits.temp_little_cool_vfloat_mv
= chip->limits.default_temp_little_cool_vfloat_mv;
chip->limits.little_cool_vfloat_over_sw_limit
= chip->limits.default_little_cool_vfloat_over_sw_limit;
chip->limits.temp_little_cool_fastchg_current_ma_high
= chip->limits.default_temp_little_cool_fastchg_current_ma_high;
chip->limits.temp_little_cool_fastchg_current_ma_low
= chip->limits.default_temp_little_cool_fastchg_current_ma_low;
chip->limits.temp_little_cold_fastchg_current_ma_high
= chip->limits.default_temp_little_cold_fastchg_current_ma_high;
chip->limits.temp_little_cold_fastchg_current_ma_low
= chip->limits.default_temp_little_cold_fastchg_current_ma_low;
chip->limits.temp_cool_fastchg_current_ma_high
= chip->limits.default_temp_cool_fastchg_current_ma_high;
chip->limits.temp_cool_fastchg_current_ma_low
= chip->limits.default_temp_cool_fastchg_current_ma_low;
chip->limits.temp_warm_fastchg_current_ma
= chip->limits.default_temp_warm_fastchg_current_ma;
chip->limits.input_current_charger_ma
= chip->limits.default_input_current_charger_ma;
chip->limits.input_current_vooc_ma_high
= chip->limits.default_input_current_vooc_ma_high;
chip->limits.input_current_vooc_ma_warm
= chip->limits.default_input_current_vooc_ma_warm;
chip->limits.input_current_vooc_ma_normal
= chip->limits.default_input_current_vooc_ma_normal;
chip->limits.pd_input_current_charger_ma
= chip->limits.default_pd_input_current_charger_ma;
chip->limits.qc_input_current_charger_ma
= chip->limits.default_qc_input_current_charger_ma;
reset_mcu_delay = 0;
#ifndef CONFIG_OPLUS_CHARGER_MTK
chip->pmic_spmi.aicl_suspend = false;
#endif
oplus_chg_battery_authenticate_check(chip);
chip->chargerid_volt = 0;
chip->chargerid_volt_got = false;
chip->short_c_batt.in_idle = true;//defualt in idle for userspace
chip->short_c_batt.cv_satus = false;//defualt not in cv chg
chip->short_c_batt.disable_rechg = false;
chip->short_c_batt.limit_chg = false;
chip->short_c_batt.limit_rechg = false;
chip->chg_ctrl_by_cool_down = false;
chip->smart_charge_user = SMART_CHARGE_USER_OTHER;
chip->usbtemp_cool_down = 0;
chip->pd_chging = false;
}
static void oplus_chg_variables_init(struct oplus_chg_chip *chip)
{
chip->charger_exist = false;
chip->chging_on = false;
chip->charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
chip->real_charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
chip->charger_volt = 0;
chip->vchg_status = CHARGER_STATUS__GOOD;
chip->prop_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
chip->sw_full_count = 0;
chip->sw_full = false;
chip->hw_full_by_sw = false;
chip->batt_exist = true;
chip->batt_full = false;
chip->tbatt_when_full = 200;
chip->recharge_after_ffc = false;
chip->tbatt_status = BATTERY_STATUS__NORMAL;
chip->tbatt_normal_status = BATTERY_STATUS__NORMAL_PHASE1;
chip->vbatt_over = 0;
chip->total_time = 0;
chip->chging_over_time = 0;
chip->in_rechging = 0;
//chip->batt_volt = 3800 * chip->vbatt_num;
chip->batt_volt = 3800;
chip->icharging = 0;
chip->temperature = 250;
chip->shell_temp = TEMPERATURE_INVALID;
chip->soc = 0;
chip->ui_soc = 50;
chip->notify_code = 0;
chip->notify_flag = 0;
chip->cool_down = 0;
chip->tbatt_pre_shake = TBATT_PRE_SHAKE_INVALID;
chip->tbatt_normal_pre_shake = TBATT_PRE_SHAKE_INVALID;
chip->led_on = true;
chip->camera_on = 0;
chip->stop_voter = 0x00;
chip->charging_state = CHARGING_STATUS_CCCV;
chip->mmi_chg = 1;
chip->unwakelock_chg = 0;
chip->chg_powersave = false;
chip->allow_swtich_to_fastchg = 1;
chip->stop_chg= 1;
chip->mmi_fastchg = 1;
chip->cool_down_done = false;
chip->healthd_ready = false;
chip->dischg_flag = false;
chip->usb_status = 0;
init_waitqueue_head( &chip->oplus_usbtemp_wq);
chip->smooth_to_soc_gap = 5;
chip->smart_charge_user = SMART_CHARGE_USER_OTHER;
chip->usbtemp_cool_down = 0;
#ifdef CONFIG_OPLUS_CHARGER_MTK
chip->usb_online = false;
chip->otg_online = false;
#else
/* chip->pmic_spmi.usb_online = false;
IC have init already */
#endif
if(chip->external_gauge) {
chg_debug("use oplus_gauge_get_batt_authenticate\n");
chip->authenticate = oplus_gauge_get_batt_authenticate();
chip->hmac = oplus_gauge_get_batt_hmac();
} else {
chg_debug("use get_oplus_high_battery_status\n");
//chip->authenticate = get_oplus_high_battery_status();
chip->authenticate = oplus_gauge_get_batt_authenticate();
chip->hmac = true;
}
if (!chip->authenticate) {
//chip->chg_ops->charger_suspend();
chip->chg_ops->charging_disable();
}
chip->otg_switch = false;
chip->ui_otg_switch = false;
chip->boot_mode = chip->chg_ops->get_boot_mode();
chip->boot_reason = chip->chg_ops->get_boot_reason();
chip->anti_shake_bound.cold_bound = chip->limits.cold_bat_decidegc;
chip->anti_shake_bound.little_cold_bound
= chip->limits.little_cold_bat_decidegc;
chip->anti_shake_bound.cool_bound = chip->limits.cool_bat_decidegc;
chip->anti_shake_bound.little_cool_bound
= chip->limits.little_cool_bat_decidegc;
chip->anti_shake_bound.normal_bound = chip->limits.normal_bat_decidegc;
chip->anti_shake_bound.warm_bound = chip->limits.warm_bat_decidegc;
chip->anti_shake_bound.hot_bound = chip->limits.hot_bat_decidegc;
chip->tbatt_normal_anti_shake_bound.phase1_bound
= chip->limits.normal_phase1_bat_decidegc;
chip->tbatt_normal_anti_shake_bound.phase2_bound
= chip->limits.normal_phase2_bat_decidegc;
chip->tbatt_normal_anti_shake_bound.phase3_bound
= chip->limits.normal_phase3_bat_decidegc;
chip->tbatt_normal_anti_shake_bound.phase4_bound
= chip->limits.normal_phase4_bat_decidegc;
chip->tbatt_normal_anti_shake_bound.phase5_bound
= chip->limits.normal_phase5_bat_decidegc;
chip->tbatt_normal_anti_shake_bound.phase6_bound
= chip->limits.normal_phase6_bat_decidegc;
chip->limits.led_warm_bat_decidegc_antishake
= chip->limits.led_warm_bat_decidegc;
chip->limits.led_high_bat_decidegc_antishake
= chip->limits.led_high_bat_decidegc;
chip->led_temp_change = false;
chip->limits.vooc_warm_bat_decidegc_antishake
= chip->limits.vooc_warm_bat_decidegc;
chip->limits.vooc_normal_bat_decidegc_antishake
= chip->limits.vooc_normal_bat_decidegc;
chip->vooc_temp_change = false;
if (chip->temperature > chip->limits.led_high_bat_decidegc)
chip->led_temp_status = LED_TEMP_STATUS__HIGH;
else if (chip->temperature > chip->limits.led_warm_bat_decidegc)
chip->led_temp_status = LED_TEMP_STATUS__WARM;
else
chip->led_temp_status = LED_TEMP_STATUS__NORMAL;
// chip->anti_shake_bound.overtemp_bound = chip->limits.overtemp_bat_decidegc;
chip->limits.vfloat_over_counts = 0;
chip->chargerid_volt = 0;
chip->chargerid_volt_got = false;
chip->enable_shipmode = 0;
chip->dod0_counts = 0;
chip->fastchg_to_ffc = false;
chip->fastchg_ffc_status = 0;
chip->ffc_temp_status = FFC_TEMP_STATUS__NORMAL;
chip->vooc_temp_status = VOOC_TEMP_STATUS__NORMAL;
chip->short_c_batt.err_code = oplus_short_c_batt_err_code_init();
chip->short_c_batt.is_switch_on = oplus_short_c_batt_chg_switch_init();
chip->short_c_batt.is_feature_sw_on
= oplus_short_c_batt_feature_sw_status_init();
chip->short_c_batt.is_feature_hw_on
= oplus_short_c_batt_feature_hw_status_init();
chip->short_c_batt.shortc_gpio_status = 1;
chip->short_c_batt.disable_rechg = false;
chip->short_c_batt.limit_chg = false;
chip->short_c_batt.limit_rechg = false;
chip->slave_charger_enable = false;
chip->cool_down_force_5v = false;
chip->chg_ctrl_by_cool_down = false;
chip->ui_soc_decimal = 0;
chip->ui_soc_integer = 0;
chip->last_decimal_ui_soc = 0;
chip->decimal_control = false;
chip->calculate_decimal_time = 0;
chip->boot_completed = false;
chip->pd_chging = false;
chip->pd_svooc = false;
chip->usbtemp_check = false;
}
static void oplus_chg_fail_action(struct oplus_chg_chip *chip)
{
chg_err("[BATTERY] BAD Battery status... Charging Stop !!\n");
chip->charging_state = CHARGING_STATUS_FAIL;
chip->chging_on = false;
chip->batt_full = false;
chip->tbatt_when_full = 200;
chip->in_rechging = 0;
}
#define D_RECHGING_CNT 5
static void oplus_chg_check_rechg_status(struct oplus_chg_chip *chip)
{
int recharging_vol;
int nbat_vol = chip->batt_volt;
static int rechging_cnt = 0;
if (chip->tbatt_status == BATTERY_STATUS__COLD_TEMP) { //4.0
recharging_vol = oplus_chg_get_float_voltage(chip) - 300;
} else if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP) {//4.4
recharging_vol = oplus_chg_get_float_voltage(chip) - 200;
} else {
recharging_vol = oplus_chg_get_float_voltage(chip);//warm 4.1
if (recharging_vol > chip->limits.temp_normal_vfloat_mv) {
recharging_vol = chip->limits.temp_normal_vfloat_mv;
}
recharging_vol = recharging_vol - chip->limits.recharge_mv;
}
if ((!chip->authenticate) ||(!chip->hmac)) {
recharging_vol = chip->limits.non_standard_vfloat_mv - 400;//3.80
}
if (nbat_vol <= recharging_vol) {
rechging_cnt++;
} else {
rechging_cnt = 0;
}
/*don't rechg here unless prohibit rechg is false*/
if (oplus_short_c_batt_is_disable_rechg(chip)) {
if (rechging_cnt >= D_RECHGING_CNT) {
charger_xlog_printk(CHG_LOG_CRTI,
"[Battery] disable rechg! batt_volt = %d, nReChgingVol = %d\r\n",
nbat_vol, recharging_vol);
rechging_cnt = D_RECHGING_CNT;
}
}
if (rechging_cnt > D_RECHGING_CNT) {
charger_xlog_printk(CHG_LOG_CRTI,
"[Battery] Battery rechg begin! batt_volt = %d, recharging_vol = %d\n",
nbat_vol, recharging_vol);
rechging_cnt = 0;
chip->in_rechging = true;
oplus_chg_voter_charging_start(chip, CHG_STOP_VOTER__FULL);/*now rechging!*/
}
}
static void oplus_chg_full_action(struct oplus_chg_chip *chip)
{
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY] Battery full !!\n");
oplus_chg_voter_charging_stop(chip, CHG_STOP_VOTER__FULL);
/*chip->charging_state = CHARGING_STATUS_FULL;*/
if(chip->batt_full == false) {
chip->tbatt_when_full = chip->temperature;
}
chip->batt_full = true;
chip->total_time = 0;
chip->in_rechging = false;
chip->limits.vfloat_over_counts = 0;
oplus_chg_check_rechg_status(chip);
}
#ifndef CONFIG_OPLUS_CHARGER_MTK
extern bool oplus_wpc_get_fw_updating(void);
#endif
void oplus_charger_detect_check(struct oplus_chg_chip *chip)
{
static bool charger_resumed = true;
#ifdef CONFIG_OPLUS_CHARGER_MTK
static int charger_flag = 0;
#endif
if (chip->chg_ops->check_chrdet_status()) {
oplus_chg_set_awake(chip, true);
#ifndef CONFIG_OPLUS_CHARGER_MTK
if (chip->wireless_support && oplus_wpc_get_fw_updating() == true) {
return;
}
#endif
if (chip->charger_type == POWER_SUPPLY_TYPE_UNKNOWN) {
noplug_temperature = chip->tbatt_temp;
noplug_batt_volt_max = chip->batt_volt_max;
noplug_batt_volt_min = chip->batt_volt_min;
oplus_chg_variables_reset(chip, true);
#ifdef CONFIG_OPLUS_CHARGER_MTK
if(is_meta_mode() == true){
chip->charger_type = POWER_SUPPLY_TYPE_USB;
chip->real_charger_type = POWER_SUPPLY_TYPE_USB;
} else {
chip->charger_type = chip->chg_ops->get_charger_type();
if(chip->chg_ops->get_real_charger_type) {
chip->real_charger_type = chip->chg_ops->get_real_charger_type();
}
}
if((chip->chg_ops->usb_connect)
&& (chip->charger_type == POWER_SUPPLY_TYPE_USB
|| chip->charger_type == POWER_SUPPLY_TYPE_USB_CDP)) {
chip->chg_ops->usb_connect();
charger_flag = 1;
}
#else
chip->charger_type = chip->chg_ops->get_charger_type();
if(chip->chg_ops->get_real_charger_type) {
chip->real_charger_type = chip->chg_ops->get_real_charger_type();
}
#endif
charger_xlog_printk(CHG_LOG_CRTI, "Charger in 1 charger_type=%d\n",
chip->charger_type);
if (oplus_vooc_get_fastchg_to_normal() == true
|| oplus_vooc_get_fastchg_to_warm() == true) {
charger_xlog_printk(CHG_LOG_CRTI,
"fast_to_normal or to_warm 1,don't turn on charge here\n");
if (oplus_vooc_get_reset_adapter_st()) {
oplus_chg_unsuspend_charger();
}
}
#ifndef CONFIG_OPLUS_CHARGER_MTK
else if (oplus_wireless_charge_start() == false) {
charger_xlog_printk(CHG_LOG_CRTI, "oplus_wireless_charge_start == false\n");
charger_resumed = chip->chg_ops->check_charger_resume();
oplus_chg_turn_on_charging(chip);
}
#else
else {
chg_err("enable charging\n");
charger_resumed = chip->chg_ops->check_charger_resume();
oplus_chg_turn_on_charging(chip);
}
#endif
/*chg_err("Charger in, charger_type=%d\n", chip->charger_type);*/
} else {
if (oplus_vooc_get_fastchg_to_normal() == true
|| oplus_vooc_get_fastchg_to_warm() == true) {
if (oplus_vooc_get_reset_adapter_st()) {
oplus_chg_unsuspend_charger();
}
charger_xlog_printk(CHG_LOG_CRTI,
"fast_to_normal or to_warm 2,don't turn on charge here\n");
if (oplus_vooc_get_reset_adapter_st()) {
oplus_chg_unsuspend_charger();
}
} else if (oplus_vooc_get_fastchg_started() == false
&& charger_resumed == false) {
charger_resumed = chip->chg_ops->check_charger_resume();
oplus_chg_turn_on_charging(chip);
}
}
} else {
oplus_chg_variables_reset(chip, false);
if (!chip->mmi_fastchg) {
oplus_mmi_fastchg_in(chip);
}
oplus_gauge_set_batt_full(false);
#ifdef CONFIG_OPLUS_CHARGER_MTK
if (chip->chg_ops->usb_disconnect && charger_flag == 1) {
chip->chg_ops->usb_disconnect();
charger_flag = 0;
}
#endif
if (chip->chg_ops->get_charging_enable() == true) {
oplus_chg_turn_off_charging(chip);
}
#ifdef CONFIG_OPLUS_CHARGER_MTK
if (chip->boot_mode != KERNEL_POWER_OFF_CHARGING_BOOT) {
oplus_chg_set_awake(chip, false);
}
#else
oplus_chg_set_awake(chip, false);
#endif
}
}
static void oplus_get_smooth_soc_switch(struct oplus_chg_chip *chip)
{
/*
char *substr;
static int save_num = -1;
if (save_num == -1) {
substr = strstr(saved_command_line, "smooth_soc_switch=");
if(NULL == substr) {
save_num = 0;
} else {
substr += strlen("smooth_soc_switch=");
if (strncmp(substr, "1", 1) == 0) {
save_num = 1;
} else
save_num = 0;
}
}
chip->smooth_switch = save_num;
if(chip->vbatt_num == 1)
chip->smooth_switch = 1;
else
chip->smooth_switch = 0;*/
chg_debug("smooth_switch = %d\n", chip->smooth_switch);
}
#define RETRY_COUNTS 24
static void oplus_chg_get_battery_data(struct oplus_chg_chip *chip)
{
static int ui_soc_cp_flag = 0;
static int soc_load = 0;
int remain_100_thresh = 97;
static int retry_counts = 0;
if (oplus_vooc_get_fastchg_started() == true) {
chip->batt_volt = oplus_gauge_get_prev_batt_mvolts();
chip->batt_volt_max = oplus_gauge_get_prev_batt_mvolts_2cell_max();
chip->batt_volt_min = oplus_gauge_get_prev_batt_mvolts_2cell_min();
chip->icharging = oplus_gauge_get_prev_batt_current();
chip->temperature = oplus_chg_match_temp_for_chging();
chip->soc = oplus_gauge_get_prev_batt_soc();
chip->batt_rm = oplus_gauge_get_prev_remaining_capacity() * chip->vbatt_num;
} else {
chip->batt_volt = oplus_gauge_get_batt_mvolts();
chip->batt_volt_max = oplus_gauge_get_batt_mvolts_2cell_max();
chip->batt_volt_min = oplus_gauge_get_batt_mvolts_2cell_min();
chip->icharging = oplus_gauge_get_batt_current();
chip->temperature = oplus_chg_match_temp_for_chging();
chip->soc = oplus_gauge_get_batt_soc();
chip->batt_fcc = oplus_gauge_get_batt_fcc() * chip->vbatt_num;
chip->batt_cc = oplus_gauge_get_batt_cc() * chip->vbatt_num;
chip->batt_soh = oplus_gauge_get_batt_soh();
chip->batt_rm = oplus_gauge_get_remaining_capacity() * chip->vbatt_num;
oplus_midas_chg_processing(chip);
}
if (chgr_dbg_vchg != 0) {
chip->charger_volt = chgr_dbg_vchg;
} else {
if (oplus_vooc_get_allow_reading() == true) {
chip->charger_volt = chip->chg_ops->get_charger_volt();
if (chip->charger_volt > 3000 && chip->charger_exist) {
chip->usbtemp_check = true;
wake_up_interruptible(&chip->oplus_usbtemp_wq);
} else {
chip->usbtemp_check = false;
}
}
}
if ((chip->chg_ops->get_charger_current && oplus_vooc_get_allow_reading() == true)
&& (chip->chg_ops->get_charging_enable && (chip->chg_ops->get_charging_enable() == true))) {
chip->ibus = chip->chg_ops->get_charger_current();
} else {
chip->ibus = -1;
}
if(chip->smooth_switch ){
oplus_chg_smooth_to_soc(chip);
} else {
chip->smooth_soc = chip->soc;
}
if(!chip->healthd_ready && chip->smooth_switch == 1 && retry_counts < RETRY_COUNTS) {
chg_err(" test gauge soc[%d] \n", chip->soc);
chip->soc = -1;
}
if (ui_soc_cp_flag == 0) {
if ((chip->soc < 0 || chip->soc > 100) && retry_counts < RETRY_COUNTS) {
charger_xlog_printk(CHG_LOG_CRTI,
"[Battery]oplus_chg_get_battery_data,\
chip->soc[%d],retry_counts[%d]\n",
chip->soc, retry_counts);
retry_counts++;
chip->soc = 50;
goto next;
}
ui_soc_cp_flag = 1;
if( chip->chg_ops->get_rtc_soc() > 100 || (chip->chg_ops->get_rtc_soc() <= 0)){
soc_load = chip->soc;
} else {
soc_load = chip->chg_ops->get_rtc_soc();
}
chip->soc_load = soc_load;
if(chip->smooth_switch)
chip->smooth_soc = soc_load;
if ((chip->soc < 0 || chip->soc > 100) && soc_load > 0 && soc_load <= 100) {
chip->soc = soc_load;
}
if ((soc_load != 0) && ((abs(soc_load-chip->soc)) <= 20)) {
if (chip->suspend_after_full && chip->external_gauge) {
remain_100_thresh = 95;
} else if (chip->suspend_after_full && !chip->external_gauge) {
remain_100_thresh = 94;
} else if (!chip->suspend_after_full && chip->external_gauge) {
remain_100_thresh = 97;
} else if (!chip->suspend_after_full && !chip->external_gauge) {
remain_100_thresh = 95;
} else {
remain_100_thresh = 97;
}
if (chip->soc < soc_load && chip->smooth_switch == 1) {
if (soc_load == 100 && chip->soc > remain_100_thresh) {
chip->ui_soc = soc_load;
} else {
chip->ui_soc = soc_load - 1;
}
} else {
chip->ui_soc = soc_load;
}
} else {
chip->ui_soc = chip->soc;
if (!chip->external_gauge && soc_load == 0 && chip->soc < 5) {
chip->ui_soc = 0;
}
}
chg_err("[soc ui_soc soc_load smooth_soc smooth_switch] = [%d %d %d %d %d]\n", chip->soc,
chip->ui_soc, chip->soc_load, chip->smooth_soc, chip->smooth_switch);
}
next:
return;
}
/*need to extend it*/
static void oplus_chg_set_aicl_point(struct oplus_chg_chip *chip)
{
if (oplus_vooc_get_allow_reading() == true) {
chip->chg_ops->set_aicl_point(chip->batt_volt);
}
}
#define AICL_DELAY_15MIN 180
static void oplus_chg_check_aicl_input_limit(struct oplus_chg_chip *chip)
{
static int aicl_delay_count = 0;
#ifdef CONFIG_OPLUS_CHARGER_MTK
if (chip->charging_state == CHARGING_STATUS_FAIL || chip->batt_full == true
|| ((chip->tbatt_status != BATTERY_STATUS__NORMAL)
&& (chip->tbatt_status != BATTERY_STATUS__LITTLE_COOL_TEMP))
|| chip->ui_soc > 85 || oplus_vooc_get_fastchg_started() == true) {
aicl_delay_count = 0;
return;
}
if (aicl_delay_count > AICL_DELAY_15MIN) {
aicl_delay_count = 0;
if (oplus_vooc_get_allow_reading() == true) {
if (chip->dual_charger_support) {
chip->slave_charger_enable = false;
oplus_chg_set_charging_current(chip);
}
oplus_chg_set_input_current_limit(chip);
}
} else {
aicl_delay_count++;
}
#else
if (chip->charging_state == CHARGING_STATUS_FAIL || chip->batt_full == true
|| ((chip->tbatt_status != BATTERY_STATUS__NORMAL)
&& (chip->tbatt_status != BATTERY_STATUS__LITTLE_COOL_TEMP))
|| ((chip->ui_soc > 85) && (chip->pmic_spmi.aicl_suspend == false))
|| oplus_vooc_get_fastchg_started() == true) {
aicl_delay_count = 0;
return;
}
if (aicl_delay_count > AICL_DELAY_15MIN) {
aicl_delay_count = 0;
if (oplus_vooc_get_allow_reading() == true) {
oplus_chg_set_input_current_limit(chip);
}
} else if (chip->pmic_spmi.aicl_suspend == true
&& chip->charger_volt > 4450
&& chip->charger_volt < 5800) {
aicl_delay_count = 0;
if (oplus_vooc_get_allow_reading() == true) {
chip->chg_ops->rerun_aicl();
oplus_chg_set_input_current_limit(chip);
}
charger_xlog_printk(CHG_LOG_CRTI, "chip->charger_volt=%d\n", chip->charger_volt);
} else {
aicl_delay_count++;
}
if (chip->charger_type == POWER_SUPPLY_TYPE_USB
|| chip->charger_type == POWER_SUPPLY_TYPE_USB_CDP) {
chip->pmic_spmi.usb_hc_count++;
if (chip->pmic_spmi.usb_hc_count >= 3) {
chip->pmic_spmi.usb_hc_mode = true;
chip->pmic_spmi.usb_hc_count = 3;
}
}
if (oplus_vooc_get_allow_reading() == true
&& chip->pmic_spmi.usb_hc_mode && !chip->pmic_spmi.hc_mode_flag) {
oplus_chg_set_input_current_limit(chip);
chip->pmic_spmi.hc_mode_flag = true;
}
#endif
}
static void oplus_chg_aicl_check(struct oplus_chg_chip *chip)
{
if (oplus_vooc_get_fastchg_started() == false) {
oplus_chg_set_aicl_point(chip);
oplus_chg_check_aicl_input_limit(chip);
}
}
static void oplus_chg_protection_check(struct oplus_chg_chip *chip)
{
if (false == oplus_chg_check_tbatt_is_good(chip)) {
chg_err("oplus_chg_check_tbatt_is_good func ,false!\n");
oplus_chg_voter_charging_stop(chip, CHG_STOP_VOTER__BATTTEMP_ABNORMAL);
} else {
if ((chip->stop_voter & CHG_STOP_VOTER__BATTTEMP_ABNORMAL)
== CHG_STOP_VOTER__BATTTEMP_ABNORMAL) {
charger_xlog_printk(CHG_LOG_CRTI,
"oplus_chg_check_tbatt_is_good func ,true! To Normal\n");
oplus_chg_voter_charging_start(chip, CHG_STOP_VOTER__BATTTEMP_ABNORMAL);
}
}
if (false == oplus_chg_check_vchg_is_good(chip)) {
chg_err("oplus_chg_check_vchg_is_good func ,false!\n");
oplus_chg_voter_charging_stop(chip, CHG_STOP_VOTER__VCHG_ABNORMAL);
} else {
if ((chip->stop_voter & CHG_STOP_VOTER__VCHG_ABNORMAL)
== CHG_STOP_VOTER__VCHG_ABNORMAL) {
charger_xlog_printk(CHG_LOG_CRTI,
"oplus_chg_check_vchg_is_good func ,true! To Normal\n");
oplus_chg_voter_charging_start(chip, CHG_STOP_VOTER__VCHG_ABNORMAL);
}
}
#ifdef FEATURE_VBAT_PROTECT
if (false == oplus_chg_check_vbatt_is_good(chip)) {
chg_err("oplus_chg_check_vbatt_is_good func ,false!\n");
oplus_chg_voter_charging_stop(chip, CHG_STOP_VOTER__VBAT_TOO_HIGH);
}
#endif
if (false == oplus_chg_check_time_is_good(chip)) {
chg_err("oplus_chg_check_time_is_good func ,false!\n");
oplus_chg_voter_charging_stop(chip, CHG_STOP_VOTER__MAX_CHGING_TIME);
}
oplus_chg_check_vbatt_higher_than_4180mv(chip);
oplus_chg_vfloat_over_check(chip);
oplus_chg_check_ffc_temp_status(chip);
if (chip->chg_ctrl_by_lcd) {
oplus_chg_check_tled_status(chip);
oplus_chg_check_led_on_ichging(chip);
}
if (chip->chg_ctrl_by_camera) {
oplus_chg_check_camera_on_ichging(chip);
}
if (chip->chg_ctrl_by_calling) {
oplus_chg_check_calling_on_ichging(chip);
}
if (chip->chg_ctrl_by_vooc) {
oplus_chg_check_vooc_temp_status(chip);
oplus_chg_check_vooc_ichging(chip);
}
if (chip->cool_down_done) {
oplus_chg_check_cool_down_ichging(chip);
}
}
static void battery_notify_tbat_check(struct oplus_chg_chip *chip)
{
static int count_removed = 0;
static int count_high = 0;
if (BATTERY_STATUS__HIGH_TEMP == chip->tbatt_status) {
count_high++;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] bat_temp(%d), BATTERY_STATUS__HIGH_TEMP count[%d]\n",
chip->temperature, count_high);
if (chip->charger_exist && count_high > 10) {
count_high = 11;
chip->notify_code |= 1 << NOTIFY_BAT_OVER_TEMP;
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY] bat_temp(%d) > 55'C\n",
chip->temperature);
}
} else {
count_high = 0;
}
if (BATTERY_STATUS__LOW_TEMP == chip->tbatt_status) {
if (chip->charger_exist) {
chip->notify_code |= 1 << NOTIFY_BAT_LOW_TEMP;
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY] bat_temp(%d) < -10'C\n",
chip->temperature);
}
}
if (BATTERY_STATUS__REMOVED == chip->tbatt_status) {
count_removed ++;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] bat_temp(%d), BATTERY_STATUS__REMOVED count[%d]\n",
chip->temperature, count_removed);
if (count_removed > 10) {
count_removed = 11;
chip->notify_code |= 1 << NOTIFY_BAT_NOT_CONNECT;
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY] bat_temp(%d) < -19'C\n",
chip->temperature);
}
} else {
count_removed = 0;
}
}
static void battery_notify_authenticate_check(struct oplus_chg_chip *chip)
{
if (!chip->authenticate) {
chip->notify_code |= 1 << NOTIFY_BAT_NOT_CONNECT;
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY] bat_authenticate is false!\n");
}
}
static void battery_notify_hmac_check(struct oplus_chg_chip *chip)
{
if (!chip->hmac) {
chip->notify_code |= 1 << NOTIFY_BAT_FULL_THIRD_BATTERY;
charger_xlog_printk(CHG_LOG_CRTI, "[BATTERY] bat_hmac is false!\n");
}
}
static void battery_notify_vcharger_check(struct oplus_chg_chip *chip)
{
if (CHARGER_STATUS__VOL_HIGH == chip->vchg_status) {
chip->notify_code |= 1 << NOTIFY_CHARGER_OVER_VOL;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] check_charger_off_vol(%d) > 5800mV\n", chip->charger_volt);
}
if (CHARGER_STATUS__VOL_LOW == chip->vchg_status) {
chip->notify_code |= 1 << NOTIFY_CHARGER_LOW_VOL;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] check_charger_off_vol(%d) < 3400mV\n", chip->charger_volt);
}
}
static void battery_notify_vbat_check(struct oplus_chg_chip *chip)
{
static int count = 0;
if (true == chip->vbatt_over) {
count++;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] Battery is over VOL, count[%d] \n", count);
if (count > 10) {
count = 11;
chip->notify_code |= 1 << NOTIFY_BAT_OVER_VOL;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] Battery is over VOL! Notify \n");
}
} else {
count = 0;
if ((chip->batt_full) && (chip->charger_exist)) {
if (chip->tbatt_status == BATTERY_STATUS__WARM_TEMP
&& chip->ui_soc != 100) {
chip->notify_code |= 1 << NOTIFY_BAT_FULL_PRE_HIGH_TEMP;
} else if ((chip->tbatt_status == BATTERY_STATUS__COLD_TEMP)
&& (chip->ui_soc != 100)) {
chip->notify_code |= 1 << NOTIFY_BAT_FULL_PRE_LOW_TEMP;
} else if (!chip->authenticate) {
chip->notify_code |= 1 << NOTIFY_BAT_NOT_CONNECT;
} else if (!chip->hmac) {
chip->notify_code |= 1 << NOTIFY_BAT_FULL_THIRD_BATTERY;
} else {
if (chip->ui_soc == 100) {
chip->notify_code |= 1 << NOTIFY_BAT_FULL;
}
}
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] FULL,tbatt_status:%d,notify_code:%d\n",
chip->tbatt_status, chip->notify_code);
}
}
}
static void battery_notify_max_charging_time_check(struct oplus_chg_chip *chip)
{
if (true == chip->chging_over_time) {
chip->notify_code |= 1 << NOTIFY_CHGING_OVERTIME;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] Charging is OverTime!Notify \n");
}
}
static void battery_notify_short_c_battery_check(struct oplus_chg_chip *chip)
{
if (chip->short_c_batt.err_code == SHORT_C_BATT_STATUS__CV_ERR_CODE1) {
chip->notify_code |= 1 << NOTIFY_SHORT_C_BAT_CV_ERR_CODE1;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] battery is short circuit! err_code1!\n");
}
if (chip->short_c_batt.err_code == SHORT_C_BATT_STATUS__FULL_ERR_CODE2) {
chip->notify_code |= 1 << NOTIFY_SHORT_C_BAT_FULL_ERR_CODE2;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] battery is short circuit! err_code2!\n");
}
if (chip->short_c_batt.err_code == SHORT_C_BATT_STATUS__FULL_ERR_CODE3) {
chip->notify_code |= 1 << NOTIFY_SHORT_C_BAT_FULL_ERR_CODE3;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] battery is short circuit! err_code3!\n");
}
if (chip->short_c_batt.err_code == SHORT_C_BATT_STATUS__DYNAMIC_ERR_CODE4) {
chip->notify_code |= 1 << NOTIFY_SHORT_C_BAT_DYNAMIC_ERR_CODE4;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] battery is short circuit! err_code4!\n");
}
if (chip->short_c_batt.err_code == SHORT_C_BATT_STATUS__DYNAMIC_ERR_CODE5) {
chip->notify_code |= 1 << NOTIFY_SHORT_C_BAT_DYNAMIC_ERR_CODE5;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] battery is short circuit! err_code5!\n");
}
}
static void battery_notify_flag_check(struct oplus_chg_chip *chip)
{
if (chip->notify_code & (1 << NOTIFY_CHGING_OVERTIME)) {
chip->notify_flag = NOTIFY_CHGING_OVERTIME;
} else if (chip->notify_code & (1 << NOTIFY_CHARGER_OVER_VOL)) {
chip->notify_flag = NOTIFY_CHARGER_OVER_VOL;
} else if (chip->notify_code & (1 << NOTIFY_CHARGER_LOW_VOL)) {
chip->notify_flag = NOTIFY_CHARGER_LOW_VOL;
} else if (chip->notify_code & (1 << NOTIFY_BAT_OVER_TEMP)) {
chip->notify_flag = NOTIFY_BAT_OVER_TEMP;
} else if (chip->notify_code & (1 << NOTIFY_BAT_LOW_TEMP)) {
chip->notify_flag = NOTIFY_BAT_LOW_TEMP;
} else if (chip->notify_code & (1 << NOTIFY_BAT_NOT_CONNECT)) {
chip->notify_flag = NOTIFY_BAT_NOT_CONNECT;
} else if (chip->notify_code & (1 << NOTIFY_BAT_FULL_THIRD_BATTERY)) {
chip->notify_flag = NOTIFY_BAT_FULL_THIRD_BATTERY;
} else if (chip->notify_code & (1 << NOTIFY_BAT_OVER_VOL)) {
chip->notify_flag = NOTIFY_BAT_OVER_VOL;
} else if (chip->notify_code & (1 << NOTIFY_BAT_FULL_PRE_HIGH_TEMP)) {
chip->notify_flag = NOTIFY_BAT_FULL_PRE_HIGH_TEMP;
} else if (chip->notify_code & (1 << NOTIFY_BAT_FULL_PRE_LOW_TEMP)) {
chip->notify_flag = NOTIFY_BAT_FULL_PRE_LOW_TEMP;
} else if (chip->notify_code & (1 << NOTIFY_BAT_FULL)) {
chip->notify_flag = NOTIFY_BAT_FULL;
} else {
chip->notify_flag = 0;
}
}
static void battery_notify_charge_terminal_check(struct oplus_chg_chip *chip)
{
if (chip->batt_full == true && chip->charger_exist == true){
chip->notify_code |= 1 << NOTIFY_CHARGER_TERMINAL;
}
}
static void battery_notify_gauge_i2c_err_check(struct oplus_chg_chip *chip)
{
if (oplus_gauge_get_i2c_err() > 0) {
chip->notify_code |= 1 << NOTIFY_GAUGE_I2C_ERR;
}
oplus_gauge_clear_i2c_err();
}
static void oplus_chg_battery_notify_check(struct oplus_chg_chip *chip)
{
chip->notify_code = 0x0000;
battery_notify_tbat_check(chip);
battery_notify_authenticate_check(chip);
battery_notify_hmac_check(chip);
battery_notify_vcharger_check(chip);
battery_notify_vbat_check(chip);
battery_notify_max_charging_time_check(chip);
battery_notify_short_c_battery_check(chip);
battery_notify_charge_terminal_check(chip);
battery_notify_gauge_i2c_err_check(chip);
battery_notify_flag_check(chip);
}
int oplus_chg_get_prop_batt_health(struct oplus_chg_chip *chip)
{
int bat_health = POWER_SUPPLY_HEALTH_GOOD;
bool vbatt_over = chip->vbatt_over;
OPLUS_CHG_TBATT_STATUS tbatt_status = chip->tbatt_status;
if (vbatt_over == true) {
bat_health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
} else if (tbatt_status == BATTERY_STATUS__REMOVED) {
bat_health = POWER_SUPPLY_HEALTH_DEAD;
} else if (tbatt_status == BATTERY_STATUS__HIGH_TEMP) {
bat_health = POWER_SUPPLY_HEALTH_OVERHEAT;
} else if (tbatt_status == BATTERY_STATUS__LOW_TEMP) {
bat_health = POWER_SUPPLY_HEALTH_COLD;
} else {
bat_health = POWER_SUPPLY_HEALTH_GOOD;
}
return bat_health;
}
static bool oplus_chg_soc_reduce_slow_when_1(struct oplus_chg_chip *chip)
{
static int reduce_count = 0;
int reduce_count_limit = 0;
if (chip->batt_exist == false) {
return false;
}
if (chip->charger_exist) {
reduce_count_limit = 12;
} else {
reduce_count_limit = 4;
}
if (chip->batt_volt_min < chip->vbatt_soc_1) {
reduce_count++;
} else {
reduce_count = 0;
}
charger_xlog_printk(CHG_LOG_CRTI,
"batt_vol:%d, batt_volt_min:%d, reduce_count:%d\n",
chip->batt_volt, chip->batt_volt_min, reduce_count);
if (reduce_count > reduce_count_limit) {
reduce_count = reduce_count_limit + 1;
return true;
} else {
return false;
}
}
#define SOC_SYNC_UP_RATE_10S 2
#define SOC_SYNC_UP_RATE_60S 12
#define SOC_SYNC_DOWN_RATE_300S 60
#define SOC_SYNC_DOWN_RATE_150S 30
#define SOC_SYNC_DOWN_RATE_90S 18
#define SOC_SYNC_DOWN_RATE_60S 12
#define SOC_SYNC_DOWN_RATE_45S 9
#define SOC_SYNC_DOWN_RATE_40S 8
#define SOC_SYNC_DOWN_RATE_30S 6
#define SOC_SYNC_DOWN_RATE_15S 3
#define TEN_MINUTES 600
#define CHARGING_STATUS 1
#define DISCHARGING_STATUS 0
static void oplus_chg_smooth_to_soc(struct oplus_chg_chip *chip)
{
static int time = 0;
static int capacity = -1;
static int smooth_diff =-1;
static int soc_pre = -1;
static int status = DISCHARGING_STATUS;
pr_err("[oplus_chg_smooth_to_soc] enter the func");
if(chip->charger_exist && chip->batt_exist
&& (CHARGING_STATUS_FAIL != chip->charging_state)
&& chip->mmi_chg && (chip->stop_chg == 1 || chip->charger_type == 5) && status == DISCHARGING_STATUS){
status = CHARGING_STATUS;
time = 0;
capacity = chip->batt_rm;
soc_pre = chip->soc;
smooth_diff = capacity/(2 * chip->soc - chip->smooth_soc);
} else if(!(chip->charger_exist && chip->batt_exist
&& chip->mmi_chg && (chip->batt_full || CHARGING_STATUS_FAIL != chip->charging_state)
&& (chip->stop_chg == 1 || chip->charger_type == 5)) && status == CHARGING_STATUS){
status = DISCHARGING_STATUS;
time = 0;
capacity = -1;
soc_pre = -1;
smooth_diff = -1;
}
if(status == DISCHARGING_STATUS){
if(chip->soc >= 96 && chip->soc <= 100 && chip->ui_soc == 100){
chip->smooth_soc = 100;
} else{
if(chip->smooth_soc > chip->soc){
if(capacity == -1){
time = 0;
capacity = chip->batt_rm;
soc_pre = chip->soc;
smooth_diff = capacity/chip->smooth_soc;
}
if((capacity - chip->batt_rm) >= smooth_diff || ((chip->smooth_soc - chip->soc) > chip->smooth_to_soc_gap)){
chip->smooth_soc--;
capacity = chip->batt_rm;
smooth_diff = capacity/chip->smooth_soc;
}
if(chip->soc == 0 ){
time++;
if(time >= SOC_SYNC_DOWN_RATE_15S){
chip->smooth_soc--;
time = 0;
}
}
pr_err("[oplus_chg_smooth_to_soc] smooth_soc[%d],capacity[%d],smooth_diff[%d]",chip->smooth_soc,capacity,smooth_diff);
} else {
chip->smooth_soc =chip->soc;
}
}
} else{
if(chip->smooth_soc > chip->soc){
if(soc_pre < chip->soc &&(chip->batt_rm - capacity) >= smooth_diff && chip->smooth_soc < 100 ){
chip->smooth_soc++;
capacity = chip->batt_rm;
soc_pre = chip->soc;
smooth_diff = capacity/(2 * chip->soc - chip->smooth_soc);
}
if(chip->soc < soc_pre){
chip->smooth_soc--;
soc_pre = chip->soc;
}
pr_err("[oplus_chg_smooth_to_soc]charging smooth_soc[%d],capacity[%d],smooth_diff[%d],soc_pre[%d]",chip->smooth_soc,capacity,smooth_diff,soc_pre);
} else {
chip->smooth_soc = chip->soc;
}
}
}
static void oplus_chg_update_ui_soc(struct oplus_chg_chip *chip)
{
static int soc_down_count = 0;
static int soc_up_count = 0;
static int ui_soc_pre = 50;
static int cnt = 0;
int soc_down_limit = 0;
int soc_up_limit = 0;
unsigned long sleep_tm = 0;
unsigned long soc_reduce_margin = 0;
bool vbatt_too_low = false;
vbatt_lowerthan_3300mv = false;
if (chip->ui_soc == 100) {
soc_down_limit = SOC_SYNC_DOWN_RATE_300S;
} else if (chip->ui_soc >= 95) {
soc_down_limit = SOC_SYNC_DOWN_RATE_150S;
} else if (chip->ui_soc >= 60) {
soc_down_limit = SOC_SYNC_DOWN_RATE_60S;
} else if (chip->charger_exist && chip->ui_soc == 1) {
soc_down_limit = SOC_SYNC_DOWN_RATE_90S;
} else {
soc_down_limit = SOC_SYNC_DOWN_RATE_40S;
}
if (chip->batt_exist &&
(chip->batt_volt_min < chip->vbatt_power_off)
&& (chip->batt_volt_min > 2500)) {
soc_down_limit = SOC_SYNC_DOWN_RATE_15S;
vbatt_too_low = true;
vbatt_lowerthan_3300mv = true;
charger_xlog_printk(CHG_LOG_CRTI,
"batt_volt:%d, batt_volt_min:%d, vbatt_too_low:%d\n",
chip->batt_volt, chip->batt_volt_min, vbatt_too_low);
}
if (chip->batt_full) {
soc_up_limit = SOC_SYNC_UP_RATE_10S;
} else {
soc_up_limit = SOC_SYNC_UP_RATE_10S;
}
#ifndef CONFIG_OPLUS_CHARGER_MTK
#ifndef WPC_NEW_INTERFACE
if ((chip->charger_exist || oplus_wireless_charge_start())
&& chip->batt_exist && chip->batt_full && chip->mmi_chg && (chip->stop_chg == 1 || chip->charger_type == 5)) {
#else
if ((chip->charger_exist || oplus_wpc_get_status())
&& chip->batt_exist && chip->batt_full && chip->mmi_chg && (chip->stop_chg == 1 || chip->charger_type == 5)) {
#endif
#else
if (chip->charger_exist && chip->batt_exist && chip->batt_full && chip->mmi_chg && (chip->stop_chg == 1 || chip->charger_type == 5)) {
#endif
chip->sleep_tm_sec = 0;
if (oplus_short_c_batt_is_prohibit_chg(chip)) {
chip->prop_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
} else if ((chip->hmac) &&((chip->tbatt_status == BATTERY_STATUS__NORMAL)
|| (chip->tbatt_status == BATTERY_STATUS__LITTLE_COOL_TEMP)
|| (chip->tbatt_status == BATTERY_STATUS__COOL_TEMP)
|| (chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP))) {
soc_down_count = 0;
soc_up_count++;
if (soc_up_count >= soc_up_limit) {
soc_up_count = 0;
chip->ui_soc++;
}
if (chip->ui_soc >= 100) {
chip->ui_soc = 100;
chip->prop_status = POWER_SUPPLY_STATUS_FULL;
} else {
chip->prop_status = POWER_SUPPLY_STATUS_CHARGING;
}
} else {
chip->prop_status = POWER_SUPPLY_STATUS_FULL;
}
if (chip->ui_soc != ui_soc_pre) {
chg_debug("full [soc ui_soc smooth_soc up_limit] = [%d %d %d %d]\n",
chip->soc, chip->ui_soc, chip->smooth_soc, soc_up_limit);
}
#ifndef CONFIG_OPLUS_CHARGER_MTK
#ifndef WPC_NEW_INTERFACE
} else if ((chip->charger_exist || oplus_wireless_charge_start()) && chip->batt_exist && (CHARGING_STATUS_FAIL != chip->charging_state)
&& chip->mmi_chg && (chip->stop_chg == 1 || chip->charger_type == 5)) {
#else
} else if ((chip->charger_exist || oplus_wpc_get_status()) && chip->batt_exist && (CHARGING_STATUS_FAIL != chip->charging_state)
&& chip->mmi_chg && (chip->stop_chg == 1 || chip->charger_type == 5)) {
#endif
#else
} else if (chip->charger_exist && chip->batt_exist && (CHARGING_STATUS_FAIL != chip->charging_state)
&& chip->mmi_chg && (chip->stop_chg == 1 || chip->charger_type == 5)) {
#endif
chip->sleep_tm_sec = 0;
chip->prop_status = POWER_SUPPLY_STATUS_CHARGING;
if (chip->smooth_soc == chip->ui_soc) {
soc_down_count = 0;
soc_up_count = 0;
} else if (chip->smooth_soc > chip->ui_soc) {
soc_down_count = 0;
soc_up_count++;
if (soc_up_count >= soc_up_limit) {
soc_up_count = 0;
chip->ui_soc++;
}
} else if (chip->smooth_soc < chip->ui_soc) {
soc_up_count = 0;
soc_down_count++;
if (soc_down_count >= soc_down_limit) {
soc_down_count = 0;
if(oplus_chg_show_vooc_logo_ornot() == false
|| (chip->vooc_show_ui_soc_decimal == false || !chip->decimal_control)) {
chip->ui_soc--;
}
}
}
if (chip->ui_soc != ui_soc_pre) {
chg_debug("full [soc ui_soc smooth_soc down_limit up_limit] = [%d %d %d %d %d]\n", chip->soc, chip->ui_soc, chip->smooth_soc, soc_down_limit, soc_up_limit);
}
charger_xlog_printk(CHG_LOG_CRTI, "ui_soc:%d,waiting_for_ffc:%d,fastchg_to_ffc:%d,fastchg_start:%d,chg_type=0x%x\n",
chip->ui_soc, chip->waiting_for_ffc == false, chip->fastchg_to_ffc == false,
oplus_vooc_get_fastchg_started(), oplus_vooc_get_fast_chg_type());
if (chip->ui_soc == 100
&& chip->fastchg_to_ffc == false
&& (oplus_vooc_get_fastchg_started() == false
|| oplus_vooc_get_fast_chg_type() == CHARGER_SUBTYPE_FASTCHG_VOOC)) {
if (++cnt >= 12) {
chip->batt_full = true;
chip->in_rechging = false;
chip->limits.vfloat_over_counts = 0;
oplus_chg_check_rechg_status(chip);
}
} else {
cnt = 0;
}
} else {
cnt = 0;
chip->prop_status = POWER_SUPPLY_STATUS_DISCHARGING;
soc_up_count = 0;
if (chip->smooth_soc <= chip->ui_soc || vbatt_too_low) {
if (soc_down_count > soc_down_limit) {
soc_down_count = soc_down_limit + 1;
} else {
soc_down_count++;
}
sleep_tm = chip->sleep_tm_sec;
if (chip->sleep_tm_sec > 0) {
soc_reduce_margin = chip->sleep_tm_sec / TEN_MINUTES;
if (soc_reduce_margin == 0) {
if ((chip->ui_soc - chip->smooth_soc) > 2) {
chip->ui_soc--;
soc_down_count = 0;
chip->sleep_tm_sec = 0;
}
} else if (soc_reduce_margin < (chip->ui_soc - chip->smooth_soc)) {
chip->ui_soc -= soc_reduce_margin;
soc_down_count = 0;
chip->sleep_tm_sec = 0;
} else if (soc_reduce_margin >= (chip->ui_soc - chip->smooth_soc)) {
chip->ui_soc = chip->smooth_soc;
soc_down_count = 0;
chip->sleep_tm_sec = 0;
}
}
if (soc_down_count >= soc_down_limit && (chip->smooth_soc < chip->ui_soc || vbatt_too_low)) {
chip->sleep_tm_sec = 0;
soc_down_count = 0;
chip->ui_soc--;
}
}
}
if (chip->ui_soc < 2) {
cnt = 0;
if (oplus_chg_soc_reduce_slow_when_1(chip) == true) {
chip->ui_soc = 0;
} else {
chip->ui_soc = 1;
}
}
if (chip->ui_soc != ui_soc_pre) {
ui_soc_pre = chip->ui_soc;
chip->chg_ops->set_rtc_soc(chip->ui_soc);
if (chip->chg_ops->get_rtc_soc() != chip->ui_soc) {
/*charger_xlog_printk(CHG_LOG_CRTI, "set soc fail:[%d, %d], try again...\n", chip->ui_soc, chip->chg_ops->get_rtc_soc());*/
chip->chg_ops->set_rtc_soc(chip->ui_soc);
}
}
if(chip->decimal_control) {
soc_down_count = 0;
soc_up_count = 0;
}
}
static void fg_update(struct oplus_chg_chip *chip)
{
static int ui_soc_pre_fg = 50;
static struct power_supply *bms_psy = NULL;
if (!bms_psy) {
bms_psy = power_supply_get_by_name("bms");
charger_xlog_printk(CHG_LOG_CRTI, "bms_psy null\n");
}
if (bms_psy) {
if (chip->ui_soc != ui_soc_pre_fg) {
power_supply_changed(bms_psy);
charger_xlog_printk(CHG_LOG_CRTI,
"ui_soc:%d, soc:%d, ui_soc_pre:%d \n",
chip->ui_soc, chip->soc, ui_soc_pre_fg);
}
if (chip->ui_soc != ui_soc_pre_fg) {
ui_soc_pre_fg = chip->ui_soc;
}
}
}
static void battery_update(struct oplus_chg_chip *chip)
{
oplus_chg_update_ui_soc(chip);
if (chip->fg_bcl_poll) {
fg_update(chip);
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
power_supply_changed(chip->batt_psy);
#else
power_supply_changed(&chip->batt_psy);
#endif
}
static void oplus_chg_battery_update_status(struct oplus_chg_chip *chip)
{
#ifdef CONFIG_OPLUS_CHARGER_MTK
usb_update(chip);
#endif
battery_update(chip);
}
#define RESET_MCU_DELAY_30S 6
static void oplus_chg_get_chargerid_voltage(struct oplus_chg_chip *chip)
{
if (chip->chg_ops->set_chargerid_switch_val == NULL
|| chip->chg_ops->get_chargerid_switch_val == NULL
|| chip->chg_ops->get_chargerid_volt == NULL) {
return;
} else if (chip->charger_type != POWER_SUPPLY_TYPE_USB_DCP) {
return;
}
if(chip->chg_ops->check_pdphy_ready && chip->chg_ops->check_pdphy_ready() == false){
chg_err("OPLUS CHG PD_PHY NOT READY");
return;
}
if (reset_mcu_delay > RESET_MCU_DELAY_30S){
return;
}
if (oplus_vooc_get_vooc_switch_val() == 1) {
if (chip->chargerid_volt_got == false) {
chip->chg_ops->set_chargerid_switch_val(1);
#ifdef CONFIG_OPLUS_CHARGER_MTK
if (oplus_vooc_get_fastchg_started() == false){
oplus_vooc_switch_mode(NORMAL_CHARGER_MODE);
}
usleep_range(100000, 110000);
#else
usleep_range(20000, 22000);
#endif /* CONFIG_OPLUS_CHARGER_MTK */
chip->chargerid_volt = chip->chg_ops->get_chargerid_volt();
chip->chargerid_volt_got = true;
} else {
if (chip->chg_ops->get_chargerid_switch_val() == 0) {
chip->chg_ops->set_chargerid_switch_val(1);
} else {
/* do nothing*/
}
}
} else if (oplus_vooc_get_vooc_switch_val() == 0) {
if (chip->chargerid_volt_got == false) {
chip->chg_ops->set_chargerid_switch_val(1);
oplus_vooc_set_vooc_chargerid_switch_val(1);
#ifdef CONFIG_OPLUS_CHARGER_MTK
usleep_range(100000, 110000);
#else
usleep_range(20000, 22000);
#endif /* CONFIG_OPLUS_CHARGER_MTK */
chip->chargerid_volt = chip->chg_ops->get_chargerid_volt();
chip->chargerid_volt_got = true;
oplus_vooc_set_vooc_chargerid_switch_val(0);
if (chip->vooc_project == false) {
chip->chg_ops->set_chargerid_switch_val(0);
}
} else {
if (chip->chg_ops->get_chargerid_switch_val() == 1) {
chip->chg_ops->set_chargerid_switch_val(0);
} else {
/* do nothing*/
}
}
} else {
charger_xlog_printk(CHG_LOG_CRTI, "do nothing\n");
}
}
static void oplus_chg_chargerid_switch_check(struct oplus_chg_chip *chip)
{
return oplus_chg_get_chargerid_voltage(chip);
}
#define RESET_MCU_DELAY_15S 3
static void oplus_chg_qc_config(struct oplus_chg_chip *chip);
static void oplus_chg_fast_switch_check(struct oplus_chg_chip *chip)
{
if (oplus_short_c_batt_is_prohibit_chg(chip)) {
charger_xlog_printk(CHG_LOG_CRTI, " short_c_battery, return\n");
return;
}
if (chip->mmi_chg == 0) {
charger_xlog_printk(CHG_LOG_CRTI, " mmi_chg,return\n");
return;
}
if (chip->allow_swtich_to_fastchg == false) {
charger_xlog_printk(CHG_LOG_CRTI, " allow_swtich_to_fastchg == 0,return\n");
return;
}
if ((!chip->authenticate) ||(!chip->hmac)) {
charger_xlog_printk(CHG_LOG_CRTI, "non authenticate or hmac,switch return\n");
return;
}
if (chip->notify_flag == NOTIFY_BAT_OVER_VOL) {
charger_xlog_printk(CHG_LOG_CRTI, " battery over voltage,return\n");
return;
}
#ifndef CONFIG_OPLUS_CHARGER_MTK
#ifdef SUPPORT_WPC
if (chip->wireless_support && oplus_wireless_charge_start() == true) {
charger_xlog_printk(CHG_LOG_CRTI, "is in WPC, switch return\n");
return;
}
#endif
#endif
if(chip->chg_ops->check_pdphy_ready && chip->chg_ops->check_pdphy_ready() == false){
chg_err("OPLUS CHG PD_PHY NOT READY");
return;
}
if (chip->charger_type == POWER_SUPPLY_TYPE_USB_DCP) {
if (true == opchg_get_mcu_update_state()) {
reset_mcu_delay = 0;
return;
}
if (oplus_vooc_get_fastchg_started() == false
&& reset_mcu_delay < RESET_MCU_DELAY_30S) {
oplus_vooc_switch_fast_chg();
}
if (!oplus_vooc_get_fastchg_started()
&& !oplus_vooc_get_fastchg_dummy_started()
&& !oplus_vooc_get_fastchg_to_normal()
&& !oplus_vooc_get_fastchg_to_warm()) {
if (suspend_charger) {
reset_mcu_delay = RESET_MCU_DELAY_15S;
suspend_charger = false;
oplus_vooc_set_ap_clk_high();
oplus_vooc_reset_mcu();
}
reset_mcu_delay++;
if (reset_mcu_delay == RESET_MCU_DELAY_15S) {
charger_xlog_printk(CHG_LOG_CRTI, " reset mcu again,suspend here\n");
if (suspend_charger == false) {
oplus_chg_reset_adapter();
suspend_charger = true;
chg_debug(" fastchg start failed, reset adapter\n");
} else {
oplus_vooc_set_ap_clk_high();
oplus_vooc_reset_mcu();
}
} else if (reset_mcu_delay == RESET_MCU_DELAY_30S
&& chip->vbatt_num == 2) {
suspend_charger = false;
reset_mcu_delay = RESET_MCU_DELAY_30S + 1;
charger_xlog_printk(CHG_LOG_CRTI, " RESET_MCU_DELAY_30S\n");
if (chip->charger_volt <= 7500) {
oplus_vooc_reset_fastchg_after_usbout();
chip->chg_ops->set_chargerid_switch_val(0);
if (chip->chg_ops->enable_qc_detect){
chip->chg_ops->enable_qc_detect();
}
}
}
} else {
suspend_charger = false;
}
if(reset_mcu_delay > RESET_MCU_DELAY_30S){
chip->pd_svooc = false;
}
}
}
#define FULL_COUNTS_SW 5
#define FULL_COUNTS_HW 4
static int oplus_chg_check_sw_full(struct oplus_chg_chip *chip)
{
int vbatt_full_vol_sw = 0;
if (!chip->charger_exist) {
chip->sw_full_count = 0;
chip->sw_full = false;
return false;
}
if (chip->tbatt_status == BATTERY_STATUS__COLD_TEMP) {
vbatt_full_vol_sw = chip->limits.cold_vfloat_sw_limit;
} else if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP) {
vbatt_full_vol_sw = chip->limits.little_cold_vfloat_sw_limit;
} else if (chip->tbatt_status == BATTERY_STATUS__COOL_TEMP) {
vbatt_full_vol_sw = chip->limits.cool_vfloat_sw_limit;
} else if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COOL_TEMP) {
vbatt_full_vol_sw = chip->limits.little_cool_vfloat_sw_limit;
} else if (chip->tbatt_status == BATTERY_STATUS__NORMAL) {
vbatt_full_vol_sw = chip->limits.normal_vfloat_sw_limit;
} else if (chip->tbatt_status == BATTERY_STATUS__WARM_TEMP) {
vbatt_full_vol_sw = chip->limits.warm_vfloat_sw_limit;
} else {
chip->sw_full_count = 0;
chip->sw_full = 0;
return false;
}
if ((!chip->authenticate) || (!chip->hmac)) {
vbatt_full_vol_sw = chip->limits.non_standard_vfloat_sw_limit;
}
if (oplus_short_c_batt_is_prohibit_chg(chip)) {
vbatt_full_vol_sw = chip->limits.short_c_bat_vfloat_sw_limit;
}
/* use SW Vfloat to check */
if (chip->batt_volt > vbatt_full_vol_sw) {
if (chip->icharging < 0 && (chip->icharging * -1) <= chip->limits.iterm_ma) {
chip->sw_full_count++;
if (chip->sw_full_count > FULL_COUNTS_SW) {
chip->sw_full_count = 0;
chip->sw_full = true;
}
} else if (chip->icharging >= 0) {
chip->sw_full_count++;
if (chip->sw_full_count > FULL_COUNTS_SW * 2) {
chip->sw_full_count = 0;
chip->sw_full = true;
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] Battery full by sw when icharging>=0!!\n");
}
} else {
chip->sw_full_count = 0;
chip->sw_full = false;
}
} else {
chip->sw_full_count = 0;
chip->sw_full = false;
}
return chip->sw_full;
}
static int oplus_chg_check_hw_full(struct oplus_chg_chip *chip)
{
int vbatt_full_vol_hw = 0;
static int vbat_counts_hw = 0;
static bool ret_hw = false;
if (!chip->charger_exist) {
vbat_counts_hw = 0;
ret_hw = false;
chip->hw_full_by_sw = false;
return false;
}
vbatt_full_vol_hw = oplus_chg_get_float_voltage(chip);
if (chip->tbatt_status == BATTERY_STATUS__COLD_TEMP) {
vbatt_full_vol_hw = chip->limits.temp_cold_vfloat_mv
+ chip->limits.non_normal_vterm_hw_inc;
} else if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP) {
vbatt_full_vol_hw = chip->limits.temp_little_cold_vfloat_mv
+ chip->limits.non_normal_vterm_hw_inc;
} else if (chip->tbatt_status == BATTERY_STATUS__COOL_TEMP) {
vbatt_full_vol_hw = chip->limits.temp_cool_vfloat_mv
+ chip->limits.non_normal_vterm_hw_inc;
} else if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COOL_TEMP) {
vbatt_full_vol_hw = chip->limits.temp_little_cool_vfloat_mv
+ chip->limits.non_normal_vterm_hw_inc;
} else if (chip->tbatt_status == BATTERY_STATUS__NORMAL) {
vbatt_full_vol_hw = chip->limits.temp_normal_vfloat_mv
+ chip->limits.normal_vterm_hw_inc;
} else if (chip->tbatt_status == BATTERY_STATUS__WARM_TEMP) {
vbatt_full_vol_hw = chip->limits.temp_warm_vfloat_mv
+ chip->limits.non_normal_vterm_hw_inc;
} else {
vbat_counts_hw = 0;
ret_hw = 0;
chip->hw_full_by_sw = false;
return false;
}
if ((!chip->authenticate) || (!chip->hmac)) {
vbatt_full_vol_hw = chip->limits.non_standard_vfloat_mv
+ chip->limits.non_normal_vterm_hw_inc;
}
if (oplus_short_c_batt_is_prohibit_chg(chip)) {
vbatt_full_vol_hw = chip->limits.short_c_bat_vfloat_mv
+ chip->limits.non_normal_vterm_hw_inc;
}
/* use HW Vfloat to check */
if (chip->batt_volt >= vbatt_full_vol_hw) {
vbat_counts_hw++;
if (vbat_counts_hw >= FULL_COUNTS_HW) {
vbat_counts_hw = 0;
ret_hw = true;
}
} else {
vbat_counts_hw = 0;
ret_hw = false;
}
chip->hw_full_by_sw = ret_hw;
return ret_hw;
}
#define FFC_VOLT_COUNTS 4
#define FFC_CURRENT_COUNTS 2
static void oplus_chg_ffc_variable_reset(struct oplus_chg_chip *chip)
{
chip->fastchg_to_ffc = false;
chip->fastchg_ffc_status = 0;
chip->chg_ctrl_by_lcd = chip->chg_ctrl_by_lcd_default;
chip->chg_ctrl_by_vooc = chip->chg_ctrl_by_vooc_default;
chip->limits.iterm_ma = chip->limits.default_iterm_ma;
chip->limits.normal_vfloat_sw_limit = chip->limits.default_normal_vfloat_sw_limit;
chip->limits.temp_normal_vfloat_mv = chip->limits.default_temp_normal_vfloat_mv;
chip->limits.normal_vfloat_over_sw_limit = chip->limits.default_normal_vfloat_over_sw_limit;
chip->limits.temp_normal_fastchg_current_ma = chip->limits.default_temp_normal_fastchg_current_ma;
chip->limits.temp_little_cool_fastchg_current_ma = chip->limits.default_temp_little_cool_fastchg_current_ma;
chip->limits.little_cool_vfloat_sw_limit = chip->limits.default_little_cool_vfloat_sw_limit;
chip->limits.temp_little_cool_vfloat_mv = chip->limits.default_temp_little_cool_vfloat_mv;
chip->limits.little_cool_vfloat_over_sw_limit = chip->limits.default_little_cool_vfloat_over_sw_limit;
}
static bool oplus_chg_check_ffc_status(struct oplus_chg_chip *chip)
{
static int vffc1_counts = 0;
static int vffc2_counts = 0;
static int warm_counts = 0;
static int normal_counts = 0;
static int ffc_vfloat_sw_limit = 4450;
if (chip->fastchg_to_ffc == true) {
if (chip->fastchg_ffc_status == 1) {
if (chip->batt_volt >= chip->limits.ffc1_normal_vfloat_sw_limit) {
vffc1_counts ++;
if (vffc1_counts >= FFC_VOLT_COUNTS) {
oplus_chg_turn_on_ffc2(chip);
return false;
}
}
if (chip->ffc_temp_status == FFC_TEMP_STATUS__NORMAL) {
if ((chip->icharging * -1) < (chip->limits.ff1_normal_fastchg_ma
- chip->limits.ff1_exit_step_ma)) {
normal_counts ++;
if (normal_counts >= FFC_CURRENT_COUNTS) {
oplus_chg_ffc_variable_reset(chip);
oplus_chg_turn_on_charging(chip);
return true;
}
} else {
normal_counts = 0;
}
} else if (chip->ffc_temp_status == FFC_TEMP_STATUS__WARM) {
if ((chip->icharging * -1) < (chip->limits.ff1_warm_fastchg_ma
- chip->limits.ff1_warm_exit_step_ma)) {
warm_counts ++;
if (warm_counts >= FFC_CURRENT_COUNTS) {
oplus_chg_ffc_variable_reset(chip);
oplus_chg_turn_on_charging(chip);
return true;
}
} else {
warm_counts = 0;
}
} else {
warm_counts = normal_counts = 0;
oplus_chg_ffc_variable_reset(chip);
oplus_chg_turn_on_charging(chip);
return true;
}
return false;
}
if (chip->fastchg_ffc_status == 2) {
if (chip->ffc_temp_status == FFC_TEMP_STATUS__WARM)
ffc_vfloat_sw_limit = chip->limits.ffc2_warm_vfloat_sw_limit;
else
ffc_vfloat_sw_limit = chip->limits.ffc2_normal_vfloat_sw_limit;
if (chip->batt_volt >= ffc_vfloat_sw_limit) {
vffc2_counts ++;
if (vffc2_counts >= FFC_VOLT_COUNTS) {
oplus_chg_ffc_variable_reset(chip);
oplus_chg_turn_on_charging(chip);
return true;
}
}
if (chip->ffc_temp_status == FFC_TEMP_STATUS__NORMAL) {
if ((chip->icharging * -1) < (chip->limits.ffc2_normal_fastchg_ma
- chip->limits.ffc2_exit_step_ma)) {
normal_counts ++;
if (normal_counts >= FFC_CURRENT_COUNTS) {
oplus_chg_ffc_variable_reset(chip);
oplus_chg_turn_on_charging(chip);
return true;
}
} else {
normal_counts = 0;
}
} else if (chip->ffc_temp_status == FFC_TEMP_STATUS__WARM) {
if ((chip->icharging * -1) < (chip->limits.ffc2_warm_fastchg_ma
- chip->limits.ffc2_warm_exit_step_ma)) {
warm_counts ++;
if (warm_counts >= FFC_CURRENT_COUNTS) {
oplus_chg_ffc_variable_reset(chip);
oplus_chg_turn_on_charging(chip);
return true;
}
} else {
warm_counts = 0;
}
} else {
warm_counts = normal_counts = 0;
oplus_chg_ffc_variable_reset(chip);
oplus_chg_turn_on_charging(chip);
return true;
}
}
return false;
}
vffc1_counts = 0;
vffc2_counts = 0;
warm_counts = 0;
normal_counts = 0;
return true;
}
static bool oplus_chg_check_vbatt_is_full_by_sw(struct oplus_chg_chip *chip)
{
bool ret_sw = false;
bool ret_hw = false;
if (!chip->check_batt_full_by_sw) {
return false;
}
ret_sw = oplus_chg_check_sw_full(chip);
ret_hw = oplus_chg_check_hw_full(chip);
if (ret_sw == true || ret_hw == true) {
charger_xlog_printk(CHG_LOG_CRTI,
"[BATTERY] Battery full by sw[%s] !!\n",
(ret_sw == true) ? "S" : "H");
return true;
} else {
return false;
}
}
#define FULL_DELAY_COUNTS 4
#define DOD0_COUNTS (8 * 60 / 5)
static void oplus_chg_check_status_full(struct oplus_chg_chip *chip)
{
int is_batt_full = 0;
static int fastchg_present_wait_count = 0;
if (chip->chg_ctrl_by_vooc) {
if (oplus_vooc_get_fastchg_ing() == true
&& oplus_vooc_get_fast_chg_type() != CHARGER_SUBTYPE_FASTCHG_VOOC)
return;
} else {
if (oplus_vooc_get_fastchg_ing() == true)
return;
}
if (oplus_vooc_get_allow_reading() == false) {
is_batt_full = 0;
fastchg_present_wait_count = 0;
} else {
if (((oplus_vooc_get_fastchg_to_normal()== true)
|| (oplus_vooc_get_fastchg_to_warm() == true))
&& (fastchg_present_wait_count <= FULL_DELAY_COUNTS)) {
is_batt_full = 0;
fastchg_present_wait_count++;
if (fastchg_present_wait_count == FULL_DELAY_COUNTS
&& chip->chg_ops->get_charging_enable() == false
&& chip->charging_state != CHARGING_STATUS_FULL
&& chip->charging_state != CHARGING_STATUS_FAIL) {
if (chip->ffc_support && chip->ffc_temp_status != FFC_TEMP_STATUS__HIGH
&& chip->ffc_temp_status != FFC_TEMP_STATUS__LOW) {
if (chip->vbatt_num == 2 && chip->dual_ffc == false) {
oplus_chg_turn_on_ffc2(chip);
} else {
oplus_chg_turn_on_ffc1(chip);
}
} else {
oplus_chg_turn_on_charging(chip);
}
}
} else {
is_batt_full = chip->chg_ops->read_full();
chip->hw_full = is_batt_full;
fastchg_present_wait_count = 0;
}
}
if (oplus_chg_check_ffc_status(chip) == false) {
return;
}
#ifndef CONFIG_OPLUS_CHARGER_MTK
if (chip->wireless_support == true && oplus_wpc_get_ffc_charging() == true) {
if (chip->batt_volt > chip->limits.normal_vfloat_sw_limit)
charger_xlog_printk(CHG_LOG_CRTI, "in wpc ffc charging\n");
return;
}
#endif
if ((is_batt_full == 1) || (chip->charging_state == CHARGING_STATUS_FULL)
|| oplus_chg_check_vbatt_is_full_by_sw(chip)) {
charger_xlog_printk(CHG_LOG_CRTI, "is_batt_full : %d, chip->charging_state= %d\n", is_batt_full, chip->charging_state);
oplus_chg_full_action(chip);
if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP
|| chip->tbatt_status == BATTERY_STATUS__COOL_TEMP
|| chip->tbatt_status == BATTERY_STATUS__LITTLE_COOL_TEMP
|| chip->tbatt_status == BATTERY_STATUS__NORMAL) {
oplus_gauge_set_batt_full(true);
}
if ((chip->recharge_after_full == true || chip->vbatt_num == 2)
&& (chip->tbatt_when_full <= 450 && chip->tbatt_when_full >= 0)
&& (chip->temperature <= 350 && chip->temperature >= 0)) {
chip->dod0_counts ++;
if (chip->dod0_counts == DOD0_COUNTS) {
if (chip->vbatt_num == 2){
oplus_gauge_update_battery_dod0();
//chip->in_rechging = true;
//oplus_chg_voter_charging_start(chip, CHG_STOP_VOTER__FULL);/*now rechging!*/
charger_xlog_printk(CHG_LOG_CRTI, "oplus_chg_check_status_full,dod0_counts = %d\n", chip->dod0_counts);
}
if (chip->recharge_after_full == true && chip->recharge_after_ffc == true) {
chip->in_rechging = true;
chip->sw_full_count = 0;
chip->sw_full = false;
chip->recharge_after_ffc = false;
oplus_chg_voter_charging_start(chip, CHG_STOP_VOTER__FULL);
charger_xlog_printk(CHG_LOG_CRTI, "recharge after full, dod0_counts = %d\n", chip->dod0_counts);
}
chip->dod0_counts = DOD0_COUNTS + 1;
}
}
} else if (chip->charging_state == CHARGING_STATUS_FAIL) {
oplus_chg_fail_action(chip);
} else {
chip->charging_state = CHARGING_STATUS_CCCV;
}
}
static void oplus_chg_kpoc_power_off_check(struct oplus_chg_chip *chip)
{
#ifdef CONFIG_MTK_KERNEL_POWER_OFF_CHARGING
if (chip->boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT
|| chip->boot_mode == LOW_POWER_OFF_CHARGING_BOOT) { /*vbus < 2.5V*/
if ((chip->chg_ops->check_chrdet_status() == false)
&& (chip->charger_volt < 2500)) {
msleep(1000);
charger_xlog_printk(CHG_LOG_CRTI,"pmic_thread_kthread]Unplug Charger/USB double check!\n");
if ((chip->chg_ops->check_chrdet_status() == false)
&& (chip->chg_ops->get_charger_volt() < 2500)) {
if ((oplus_vooc_get_fastchg_to_normal() == false)
&& (oplus_vooc_get_fastchg_to_warm() == false)
&& (oplus_vooc_get_adapter_update_status() != ADAPTER_FW_NEED_UPDATE)
&& (oplus_vooc_get_btb_temp_over() == false)) {
charger_xlog_printk(CHG_LOG_CRTI,
"[pmic_thread_kthread]Unplug Charger/USB \
In Kernel Power Off Charging Mode Shutdown OS!\n");
chip->chg_ops->set_power_off();
}
}
}
}
#endif
}
static void oplus_chg_print_log(struct oplus_chg_chip *chip)
{
/* wenbin.liu@SW.Bsp.Driver, 2016/02/29 Add for log tag*/
if(chip->vbatt_num == 1){
charger_xlog_printk(CHG_LOG_CRTI,
" CHGR[ %d / %d / %d / %d / %d ], "
"BAT[ %d / %d / %d / %d / %d / %d ], "
"GAUGE[ %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d / %d /], "
"STATUS[ 0x%x / %d / %d / %d / %d / 0x%x ], OTHER[ %d / %d / %d / %d / %d/ %d / %d]\n",
chip->charger_exist, chip->charger_type, chip->charger_volt,
chip->prop_status, chip->boot_mode,
chip->batt_exist, chip->batt_full, chip->chging_on, chip->in_rechging,
chip->charging_state, chip->total_time,
chip->temperature, chip->batt_volt, chip->batt_volt_min, chip->icharging,
chip->ibus, chip->soc, chip->ui_soc, chip->soc_load, chip->batt_rm,
oplus_gauge_get_batt_fc(),oplus_gauge_get_batt_qm(),
oplus_gauge_get_batt_pd(),oplus_gauge_get_batt_rcu(),
oplus_gauge_get_batt_rcf(),oplus_gauge_get_batt_fcu(),
oplus_gauge_get_batt_fcf(),oplus_gauge_get_batt_sou(),
oplus_gauge_get_batt_do0(),oplus_gauge_get_batt_doe(),
oplus_gauge_get_batt_trm(),oplus_gauge_get_batt_pc(),
oplus_gauge_get_batt_qs(),
chip->vbatt_over, chip->chging_over_time, chip->vchg_status,
chip->tbatt_status, chip->stop_voter, chip->notify_code,
chip->otg_switch, chip->mmi_chg, chip->boot_reason, chip->boot_mode,
chip->chargerid_volt, chip->chargerid_volt_got, chip->shell_temp);
}else{
if (chip->prop_status != POWER_SUPPLY_STATUS_CHARGING) {
oplus_gauge_dump_register();
}
charger_xlog_printk(CHG_LOG_CRTI,
" CHGR[ %d / %d / %d / %d / %d ], \
BAT[ %d / %d / %d / %d / %d / %d ], \
GAUGE[ %d / %d / %d / %d / %d / %d / %d / %d / %d / %d ], "
"STATUS[ 0x%x / %d / %d / %d / %d / 0x%x ], \
OTHER[ %d / %d / %d / %d / %d/ %d / %d]\n",
chip->charger_exist, chip->charger_type, chip->charger_volt,
chip->prop_status, chip->boot_mode,
chip->batt_exist, chip->batt_full, chip->chging_on, chip->in_rechging,
chip->charging_state, chip->total_time,
chip->temperature, chip->batt_volt, chip->batt_volt_min, chip->icharging,
chip->ibus, chip->soc, chip->ui_soc, chip->soc_load, chip->batt_rm,
chip->vbatt_over, chip->chging_over_time, chip->vchg_status,
chip->tbatt_status, chip->stop_voter, chip->notify_code,
chip->otg_switch, chip->mmi_chg, chip->boot_reason, chip->boot_mode,
chip->chargerid_volt, chip->chargerid_volt_got, chip->shell_temp);
}
#ifdef CONFIG_OPLUS_CHARGER_MTK
if (chip->charger_type == POWER_SUPPLY_TYPE_USB_DCP) {
oplus_vooc_print_log();
}
#endif
}
#define CHARGER_ABNORMAL_DETECT_TIME 24
static void oplus_chg_critical_log(struct oplus_chg_chip *chip)
{
static int chg_abnormal_count = 0;
if (chip->charger_exist) {
if (chip->stop_voter == 0
&& chip->charger_type == POWER_SUPPLY_TYPE_USB_DCP
&& chip->soc <= 75 && chip->icharging >= -20) {
chg_abnormal_count++;
if (chg_abnormal_count >= CHARGER_ABNORMAL_DETECT_TIME) {
chg_abnormal_count = CHARGER_ABNORMAL_DETECT_TIME;
charger_abnormal_log = CRITICAL_LOG_UNABLE_CHARGING;
}
charger_xlog_printk(CHG_LOG_CRTI, " unable charging, count=%d, charger_abnormal_log=%d\n", chg_abnormal_count, charger_abnormal_log);
} else {
chg_abnormal_count = 0;
}
if ((chip->stop_voter & CHG_STOP_VOTER__BATTTEMP_ABNORMAL)
== CHG_STOP_VOTER__BATTTEMP_ABNORMAL) {
charger_abnormal_log = CRITICAL_LOG_BATTTEMP_ABNORMAL;
} else if ((chip->stop_voter & CHG_STOP_VOTER__VCHG_ABNORMAL)
== CHG_STOP_VOTER__VCHG_ABNORMAL) {
charger_abnormal_log = CRITICAL_LOG_VCHG_ABNORMAL;
} else if ((chip->stop_voter & CHG_STOP_VOTER__VBAT_TOO_HIGH)
== CHG_STOP_VOTER__VBAT_TOO_HIGH) {
charger_abnormal_log = CRITICAL_LOG_VBAT_TOO_HIGH;
} else if ((chip->stop_voter & CHG_STOP_VOTER__MAX_CHGING_TIME)
== CHG_STOP_VOTER__MAX_CHGING_TIME) {
charger_abnormal_log = CRITICAL_LOG_CHARGING_OVER_TIME;
} else {
/*do nothing*/
}
} else if (oplus_vooc_get_btb_temp_over() == true
|| oplus_vooc_get_fastchg_to_normal() == true) {
/*Do not clear 0x5d and 0x59*/
charger_xlog_printk(CHG_LOG_CRTI, " btb_temp_over or fastchg_to_normal, charger_abnormal_log=%d\n", charger_abnormal_log);
} else {
charger_abnormal_log = 0;
}
}
int oplus_chg_get_curr_time_ms(unsigned long *time_ms)
{
u64 ts_nsec;
ts_nsec = local_clock();
*time_ms = ts_nsec / 1000000;
return *time_ms;
}
static void oplus_chg_other_thing(struct oplus_chg_chip *chip)
{
static unsigned long start_chg_time = 0;
unsigned long cur_chg_time = 0;
if (oplus_vooc_get_fastchg_started() == false) {
chip->chg_ops->kick_wdt();
chip->chg_ops->dump_registers();
}
if (chip->charger_exist) {
if (chgr_dbg_total_time != 0) {
chip->total_time = chgr_dbg_total_time;
} else {
if (!chip->total_time) {
oplus_chg_get_curr_time_ms(&start_chg_time);
start_chg_time = start_chg_time/1000;
chip->total_time += OPLUS_CHG_UPDATE_INTERVAL_SEC;
} else {
oplus_chg_get_curr_time_ms(&cur_chg_time);
cur_chg_time = cur_chg_time/1000;
chip->total_time = OPLUS_CHG_UPDATE_INTERVAL_SEC + cur_chg_time - start_chg_time;
}
}
}
oplus_chg_debug_chg_monitor(chip);
oplus_chg_print_log(chip);
oplus_chg_critical_log(chip);
#ifndef CONFIG_OPLUS_CHARGER_MTK
#ifndef WPC_NEW_INTERFACE
if(chip->wireless_support){
oplus_wpc_print_log();
chargepump_print_log();
}
#endif
#endif
}
#define IBATT_COUNT 10
static void oplus_chg_ibatt_check_and_set(struct oplus_chg_chip *chip)
{
static int average_current = 0;
static int ibatt_count = 0;
static int current_adapt = 0;
static int pre_tbatt_status = BATTERY_STATUS__INVALID;
static int fail_count = 0;
bool set_current_flag = false;
int recharge_volt = 0;
int current_limit = 0;
int current_init = 0;
int threshold = 0;
int current_step = 0;
if ((chip->chg_ops->need_to_check_ibatt
&& chip->chg_ops->need_to_check_ibatt() == false)
|| !chip->chg_ops->need_to_check_ibatt) {
return;
}
if (!chip->charger_exist || (oplus_vooc_get_fastchg_started() == true)) {
current_adapt = 0;
ibatt_count = 0;
average_current = 0;
fail_count = 0;
return;
}
if (oplus_short_c_batt_is_prohibit_chg(chip)) {
return;
}
if (current_adapt == 0) {
if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP) {
current_adapt = chip->limits.temp_little_cold_fastchg_current_ma;
pre_tbatt_status = BATTERY_STATUS__LITTLE_COLD_TEMP;
} else if (chip->tbatt_status == BATTERY_STATUS__WARM_TEMP) {
current_adapt = chip->limits.temp_warm_fastchg_current_ma;
pre_tbatt_status = BATTERY_STATUS__WARM_TEMP;
} else if (chip->tbatt_status == BATTERY_STATUS__COLD_TEMP) {
current_adapt = chip->limits.temp_cold_fastchg_current_ma;
pre_tbatt_status = BATTERY_STATUS__COLD_TEMP;
} else if (chip->tbatt_status == BATTERY_STATUS__NORMAL) {
current_adapt = chip->limits.temp_normal_fastchg_current_ma;
pre_tbatt_status = BATTERY_STATUS__NORMAL;
} else if (chip->tbatt_status == BATTERY_STATUS__COOL_TEMP) {
//if ( chip->batt_volt > (chip->vbatt_num * 4180)) {
if ( chip->batt_volt > 4180) {
current_adapt = chip->limits.temp_cool_fastchg_current_ma_low;
} else {
current_adapt = chip->limits.temp_cool_fastchg_current_ma_high;
}
pre_tbatt_status = BATTERY_STATUS__COOL_TEMP;
} else if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COOL_TEMP) {
current_adapt = chip->limits.temp_little_cool_fastchg_current_ma;
pre_tbatt_status = BATTERY_STATUS__LITTLE_COOL_TEMP;
}
}
if (chip->tbatt_status != pre_tbatt_status) {
current_adapt = 0;
ibatt_count = 0;
average_current = 0;
fail_count = 0;
return;
}
if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COLD_TEMP) {
recharge_volt = chip->limits.temp_little_cold_vfloat_mv - chip->limits.recharge_mv;
current_init = chip->limits.temp_little_cold_fastchg_current_ma;
current_limit = chip->batt_capacity_mah * 15 / 100;
threshold = 50;
} else if (chip->tbatt_status == BATTERY_STATUS__WARM_TEMP) {
recharge_volt = chip->limits.temp_warm_vfloat_mv - chip->limits.recharge_mv;
current_init = chip->limits.temp_warm_fastchg_current_ma;
current_limit = chip->batt_capacity_mah * 25 / 100;
threshold = 50;
} else if (chip->tbatt_status == BATTERY_STATUS__COLD_TEMP) {
recharge_volt = chip->limits.temp_cold_vfloat_mv - chip->limits.recharge_mv;
current_init = chip->limits.temp_cold_fastchg_current_ma;
current_limit = 350;
threshold = 50;
} else if (chip->tbatt_status == BATTERY_STATUS__NORMAL) {
recharge_volt = chip->limits.temp_normal_vfloat_mv- chip->limits.recharge_mv;
current_init = chip->limits.temp_normal_fastchg_current_ma;
if (chip->vooc_project) {
current_limit = 2000;
} else {
current_limit = chip->batt_capacity_mah * 65 / 100;
}
threshold = 70;
} else if (chip->tbatt_status == BATTERY_STATUS__COOL_TEMP) {
recharge_volt = chip->limits.temp_cool_vfloat_mv - chip->limits.recharge_mv;
if (vbatt_higherthan_4180mv) {
current_init = chip->limits.temp_cool_fastchg_current_ma_low;
current_limit = chip->batt_capacity_mah * 15 / 100;
} else {
current_init = chip->limits.temp_cool_fastchg_current_ma_high;
current_limit = chip->batt_capacity_mah * 25 / 100;
}
threshold = 50;
} else if (chip->tbatt_status == BATTERY_STATUS__LITTLE_COOL_TEMP) {
recharge_volt = chip->limits.temp_little_cool_vfloat_mv - chip->limits.recharge_mv;
current_init = chip->limits.temp_little_cool_fastchg_current_ma;
current_limit = chip->batt_capacity_mah * 45 / 100;
threshold = 70;
}
if (chip->batt_volt > recharge_volt || chip->led_on) {
ibatt_count = 0;
average_current = 0;
fail_count = 0;
return;
}
if (oplus_vooc_get_allow_reading() == true) {
current_step = chip->chg_ops->get_chg_current_step();
} else {
current_adapt = 0;
ibatt_count = 0;
average_current = 0;
fail_count = 0;
return;
}
if (chip->icharging < 0) {
ibatt_count++;
average_current = average_current + chip->icharging;
}
/*charge current larger than limit*/
if ((-1 * chip->icharging) > current_limit) {
if (current_adapt > current_init) {
current_adapt = current_init;
} else {
current_adapt -= 2 * current_step;
}
set_current_flag = true;
fail_count++;
} else if (ibatt_count == IBATT_COUNT) {
average_current = -1 * average_current / ibatt_count;
threshold += fail_count * current_step;
if (average_current < current_limit - threshold) {
current_adapt += current_step;
set_current_flag = true;
} else {
ibatt_count = 0;
average_current = 0;
}
}
if (set_current_flag == true) {
if (current_adapt > (current_limit + 100)) {
current_adapt = current_limit + 100;
} else if (current_adapt < 103) {/*(512*20%)*/
current_adapt = 103;
}
charger_xlog_printk(CHG_LOG_CRTI,
"charging_current_write_fast[%d] step[%d]\n",
current_adapt, current_step);
chip->chg_ops->charging_current_write_fast(current_adapt);
ibatt_count = 0;
average_current = 0;
}
}
static void oplus_chg_pd_config(struct oplus_chg_chip *chip)
{
int ret = 0;
if(chip->pd_svooc == true){
return;
}
if (chip->charger_type != POWER_SUPPLY_TYPE_USB_DCP) {
chip->pd_chging = false;
return;
}
if (!chip->chg_ops->oplus_chg_pd_setup
|| !chip->chg_ops->oplus_chg_get_pd_type) {
return;
}
if (chip->dual_charger_support) {
if (chip->charger_volt > 7500) {
chip->pd_chging = true;
} else {
chip->pd_chging = false;
}
}
if (chip->pd_chging == false && chip->chg_ops->oplus_chg_get_pd_type() == true
&& oplus_chg_show_vooc_logo_ornot() == false) {
ret = chip->chg_ops->oplus_chg_pd_setup();
if (ret >= 0) {
chip->pd_chging = true;
chip->limits.temp_little_cool_fastchg_current_ma
= chip->limits.pd_temp_little_cool_fastchg_current_ma;
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.pd_temp_normal_fastchg_current_ma;
chip->limits.temp_little_cold_fastchg_current_ma_high
= chip->limits.pd_temp_little_cold_fastchg_current_ma_high;
chip->limits.temp_little_cold_fastchg_current_ma_low
= chip->limits.pd_temp_little_cold_fastchg_current_ma_low;
chip->limits.temp_cool_fastchg_current_ma_high
= chip->limits.pd_temp_cool_fastchg_current_ma_high;
chip->limits.temp_cool_fastchg_current_ma_low
= chip->limits.pd_temp_cool_fastchg_current_ma_low;
chip->limits.temp_warm_fastchg_current_ma
= chip->limits.pd_temp_warm_fastchg_current_ma;
chip->limits.input_current_charger_ma
= chip->limits.pd_input_current_charger_ma;
oplus_chg_set_charging_current(chip);
oplus_chg_set_input_current_limit(chip);
oplus_chg_enable_burst_mode(true);
oplus_chg_get_charger_voltage();
}
}
}
static void oplus_chg_pdqc_to_normal(struct oplus_chg_chip *chip)
{
int ret = 0;
static int pdqc_9v = false;
if (!chip->chg_ops->get_charger_subtype) {
return;
}
if (!chip->chg_ops->oplus_chg_pd_setup || !chip->chg_ops->set_qc_config) {
return;
}
if (chip->limits.vbatt_pdqc_to_5v_thr < 0) {
return;
}
if(oplus_chg_show_vooc_logo_ornot() == true){
return;
}
if (chip->charger_volt > 7500) {
pdqc_9v = true;
} else {
pdqc_9v = false;
}
if (chip->chg_ops->get_charger_subtype() == CHARGER_SUBTYPE_PD) {
if (chip->batt_volt > chip->limits.vbatt_pdqc_to_5v_thr && pdqc_9v == true) {
ret = chip->chg_ops->oplus_chg_pd_setup();
if (ret >= 0) {
pdqc_9v = false;
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.default_temp_normal_fastchg_current_ma;
chip->limits.temp_little_cool_fastchg_current_ma
= chip->limits.default_temp_little_cool_fastchg_current_ma;
chip->limits.temp_little_cool_fastchg_current_ma_high
= chip->limits.default_temp_little_cool_fastchg_current_ma_high;
chip->limits.temp_little_cool_fastchg_current_ma_low
= chip->limits.default_temp_little_cool_fastchg_current_ma_low;
chip->limits.temp_little_cold_fastchg_current_ma_high
= chip->limits.default_temp_little_cold_fastchg_current_ma_high;
chip->limits.temp_little_cold_fastchg_current_ma_low
= chip->limits.default_temp_little_cold_fastchg_current_ma_low;
chip->limits.temp_cool_fastchg_current_ma_high
= chip->limits.default_temp_cool_fastchg_current_ma_high;
chip->limits.temp_cool_fastchg_current_ma_low
= chip->limits.default_temp_cool_fastchg_current_ma_low;
chip->limits.temp_warm_fastchg_current_ma
= chip->limits.default_temp_warm_fastchg_current_ma;
chip->limits.input_current_charger_ma
= chip->limits.default_input_current_charger_ma;
oplus_chg_set_charging_current(chip);
oplus_chg_set_input_current_limit(chip);
}
}
} else if (chip->chg_ops->get_charger_subtype() == CHARGER_SUBTYPE_QC) {
if (chip->batt_volt > chip->limits.vbatt_pdqc_to_5v_thr && pdqc_9v == true) {
ret = chip->chg_ops->set_qc_config();
if (ret >= 0) {
pdqc_9v = false;
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.default_temp_normal_fastchg_current_ma;
chip->limits.temp_little_cool_fastchg_current_ma
= chip->limits.default_temp_little_cool_fastchg_current_ma;
chip->limits.temp_little_cool_fastchg_current_ma_high
= chip->limits.default_temp_little_cool_fastchg_current_ma_high;
chip->limits.temp_little_cool_fastchg_current_ma_low
= chip->limits.default_temp_little_cool_fastchg_current_ma_low;
chip->limits.temp_little_cold_fastchg_current_ma_high
= chip->limits.default_temp_little_cold_fastchg_current_ma_high;
chip->limits.temp_little_cold_fastchg_current_ma_low
= chip->limits.default_temp_little_cold_fastchg_current_ma_low;
chip->limits.temp_cool_fastchg_current_ma_high
= chip->limits.default_temp_cool_fastchg_current_ma_high;
chip->limits.temp_cool_fastchg_current_ma_low
= chip->limits.default_temp_cool_fastchg_current_ma_low;
chip->limits.temp_warm_fastchg_current_ma
= chip->limits.default_temp_warm_fastchg_current_ma;
chip->limits.input_current_charger_ma
= chip->limits.default_input_current_charger_ma;
oplus_chg_set_charging_current(chip);
oplus_chg_set_input_current_limit(chip);
}
}
}
}
static void oplus_chg_qc_config(struct oplus_chg_chip *chip)
{
static int qc_chging = false;
int ret = 0;
if (chip->charger_type != POWER_SUPPLY_TYPE_USB_DCP) {
qc_chging = false;
return;
}
if (!chip->chg_ops->set_qc_config || !chip->chg_ops->get_charger_subtype)
return;
chg_err("chip->charger_type[%d], subtype[%d]\n",
chip->charger_type, chip->chg_ops->get_charger_subtype());
if (qc_chging == false
&& chip->chg_ops->get_charger_subtype() == CHARGER_SUBTYPE_QC) {
ret = chip->chg_ops->set_qc_config();
if (ret >= 0) {
qc_chging = true;
chg_err("QC config success");
chip->limits.temp_little_cool_fastchg_current_ma_high
= chip->limits.qc_temp_little_cool_fastchg_current_ma;
chip->limits.temp_little_cool_fastchg_current_ma_low
= chip->limits.qc_temp_little_cool_fastchg_current_ma;
chip->limits.temp_normal_fastchg_current_ma
= chip->limits.qc_temp_normal_fastchg_current_ma;
chip->limits.temp_little_cold_fastchg_current_ma_high
= chip->limits.qc_temp_little_cold_fastchg_current_ma_high;
chip->limits.temp_little_cold_fastchg_current_ma_low
= chip->limits.qc_temp_little_cold_fastchg_current_ma_low;
chip->limits.temp_cool_fastchg_current_ma_high
= chip->limits.qc_temp_cool_fastchg_current_ma_high;
chip->limits.temp_cool_fastchg_current_ma_low
= chip->limits.qc_temp_cool_fastchg_current_ma_low;
chip->limits.temp_warm_fastchg_current_ma
= chip->limits.qc_temp_warm_fastchg_current_ma;
chip->limits.input_current_charger_ma
= chip->limits.qc_input_current_charger_ma;
oplus_chg_set_input_current_limit(chip);
oplus_chg_set_charging_current(chip);
oplus_chg_enable_burst_mode(true);
oplus_chg_get_charger_voltage();
}
}
}
static void oplus_chg_dual_charger_config(struct oplus_chg_chip *chip)
{
static int enable_slave_cnt = 0;
static int disable_slave_cnt = 0;
if (!chip->dual_charger_support) {
return;
}
if (chip->charger_type != POWER_SUPPLY_TYPE_USB_DCP) {
return;
}
if (chip->chg_ops->get_charger_subtype() == CHARGER_SUBTYPE_DEFAULT) {
return;
}
if (chip->slave_charger_enable == false) {
if (chip->icharging < 0 && (chip->icharging * -1) > chip->slave_chg_enable_ma) {
enable_slave_cnt++;
} else {
enable_slave_cnt = 0;
}
if (enable_slave_cnt >= 3) {
chg_err("Enable slave charger!!\n");
chip->slave_charger_enable = true;
oplus_chg_set_input_current_limit(chip);
oplus_chg_set_charging_current(chip);
enable_slave_cnt = 0;
}
} else {
if (chip->slave_charger_enable == true) {
if (chip->icharging < 0 && (chip->icharging * -1) < chip->slave_chg_disable_ma) {
disable_slave_cnt++;
} else {
disable_slave_cnt = 0;
}
if (disable_slave_cnt >= 3) {
chg_err("Disable slave charger!!\n");
chip->slave_charger_enable = false;
oplus_chg_set_input_current_limit(chip);
oplus_chg_set_charging_current(chip);
disable_slave_cnt = 0;
}
}
}
}
static void oppo_fastchg_check_work(struct work_struct *work)
{
if(check_fastchg_quit){
fastchgquit_check();
}
}
static void oplus_chg_reset_adapter_work(struct work_struct *work) {
oplus_chg_suspend_charger();
msleep(1000);
if (g_charger_chip->mmi_chg) {
oplus_chg_unsuspend_charger();
oplus_vooc_set_ap_clk_high();
oplus_vooc_reset_mcu();
}
}
static void oplus_chg_update_work(struct work_struct *work)
{
struct delayed_work *dwork = to_delayed_work(work);
struct oplus_chg_chip *chip = container_of(dwork, struct oplus_chg_chip, update_work);
oplus_charger_detect_check(chip);
oplus_chg_get_battery_data(chip);
if (chip->charger_exist) {
oplus_chg_aicl_check(chip);
oplus_chg_protection_check(chip);
oplus_chg_check_tbatt_normal_status(chip);
oplus_chg_check_status_full(chip);
oplus_chg_battery_notify_check(chip);
oplus_chg_pd_config(chip);
oplus_chg_get_chargerid_voltage(chip);
oplus_chg_fast_switch_check(chip);
oplus_chg_chargerid_switch_check(chip);
}
oplus_chg_dual_charger_config(chip);
oplus_chg_qc_config(chip);
oplus_chg_pdqc_to_normal(chip);
oplus_chg_ibatt_check_and_set(chip);
/* oplus_chg_short_c_battery_check(chip); */
wake_up_process(chip->shortc_thread);
oplus_chg_battery_update_status(chip);
oplus_chg_kpoc_power_off_check(chip);
oplus_chg_other_thing(chip);
/* run again after interval */
schedule_delayed_work(&chip->update_work, OPLUS_CHG_UPDATE_INTERVAL);
}
void oplus_chg_cancel_update_work_sync(void)
{
if (!g_charger_chip) {
return;
}
cancel_delayed_work_sync(&g_charger_chip->update_work);
}
void oplus_chg_restart_update_work(void)
{
if (!g_charger_chip) {
return;
}
schedule_delayed_work(&g_charger_chip->update_work, 0);
}
bool oplus_chg_wake_update_work(void)
{
int shedule_work = 0;
if (!g_charger_chip) {
chg_err(" g_charger_chip NULL,return\n");
return true;
}
shedule_work = mod_delayed_work(system_wq, &g_charger_chip->update_work, 0);
return true;
}
void oplus_chg_reset_adapter(void)
{
if (!g_charger_chip) {
return;
}
schedule_delayed_work(&g_charger_chip->reset_adapter_work, 0);
}
void oplus_chg_kick_wdt(void)
{
if (!g_charger_chip) {
return;
}
if (oplus_vooc_get_allow_reading() == true) {
g_charger_chip->chg_ops->kick_wdt();
}
}
void oplus_chg_disable_charge(void)
{
if (!g_charger_chip) {
return;
}
if (oplus_vooc_get_allow_reading() == true) {
g_charger_chip->chg_ops->charging_disable();
}
}
void oplus_chg_suspend_charger(void)
{
if (!g_charger_chip) {
return;
}
if (oplus_vooc_get_allow_reading() == true) {
g_charger_chip->chg_ops->charger_suspend();
}
}
void oplus_chg_unsuspend_charger(void)
{
if (!g_charger_chip) {
return;
}
if (oplus_vooc_get_allow_reading() == true) {
g_charger_chip->chg_ops->charger_unsuspend();
}
}
int oplus_chg_get_batt_volt(void)
{
if (!g_charger_chip) {
return 4000;
} else {
return g_charger_chip->batt_volt;
}
}
int oplus_chg_get_icharging(void)
{
if (!g_charger_chip) {
return 4000;
} else {
return g_charger_chip->icharging;
}
}
int oplus_chg_get_ui_soc(void)
{
if (!g_charger_chip) {
return 50;
} else {
return g_charger_chip->ui_soc;
}
}
int oplus_chg_get_soc(void)
{
if (!g_charger_chip) {
return 50;
} else {
return g_charger_chip->soc;
}
}
void oplus_chg_soc_update_when_resume(unsigned long sleep_tm_sec)
{
int new_soc;
if (!g_charger_chip) {
return;
}
g_charger_chip->sleep_tm_sec = sleep_tm_sec;
new_soc = oplus_gauge_get_batt_soc();
if(new_soc != g_charger_chip->soc){
g_charger_chip->smooth_soc -= (g_charger_chip->soc - new_soc);
}
g_charger_chip->soc = new_soc;
if(g_charger_chip->smooth_switch){
oplus_chg_smooth_to_soc(g_charger_chip);
}
oplus_chg_update_ui_soc(g_charger_chip);
}
void oplus_chg_soc_update(void)
{
if (!g_charger_chip) {
return;
}
oplus_chg_update_ui_soc(g_charger_chip);
oplus_chg_debug_set_soc_info(g_charger_chip);
}
int oplus_chg_get_chg_type(void)
{
if (!g_charger_chip) {
return POWER_SUPPLY_TYPE_UNKNOWN;
} else {
return g_charger_chip->charger_type;
}
}
int oplus_chg_get_chg_temperature(void)
{
if (!g_charger_chip) {
return 250;
} else {
return g_charger_chip->temperature;
}
}
int oplus_chg_get_notify_flag(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->notify_flag;
}
}
int oplus_is_vooc_project(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->vooc_project;
}
}
int oplus_chg_show_vooc_logo_ornot(void)
{
if (!g_charger_chip) {
return 0;
}
#ifndef CONFIG_OPLUS_CHARGER_MTK
if (g_charger_chip->wireless_support
&& oplus_wpc_get_adapter_type() == CHARGER_SUBTYPE_FASTCHG_SVOOC
&& g_charger_chip->prop_status != POWER_SUPPLY_STATUS_FULL
&& (g_charger_chip->stop_voter == CHG_STOP_VOTER__FULL
|| g_charger_chip->stop_voter == CHG_STOP_VOTER_NONE))
return 1;
#endif
if (g_charger_chip->chg_ctrl_by_vooc) {
if (oplus_vooc_get_fastchg_started() == true
&& oplus_vooc_get_fast_chg_type() == CHARGER_SUBTYPE_FASTCHG_VOOC) {
//chg_err("show_vooc_logo_ornot by vooc\n");
if (g_charger_chip->prop_status != POWER_SUPPLY_STATUS_FULL
&& (g_charger_chip->stop_voter == CHG_STOP_VOTER__FULL
|| g_charger_chip->stop_voter == CHG_STOP_VOTER_NONE)) {
return 1;
} else {
return 0;
}
}
}
if (oplus_vooc_get_fastchg_started()) {
return 1;
} else if (oplus_vooc_get_fastchg_to_normal() == true
|| oplus_vooc_get_fastchg_to_warm() == true
|| oplus_vooc_get_fastchg_dummy_started() == true
|| oplus_vooc_get_adapter_update_status() == ADAPTER_FW_NEED_UPDATE) {
if (g_charger_chip->prop_status != POWER_SUPPLY_STATUS_FULL
&&(g_charger_chip->stop_voter == CHG_STOP_VOTER__FULL
|| g_charger_chip->stop_voter == CHG_STOP_VOTER_NONE
|| g_charger_chip->stop_voter == CHG_STOP_VOTER__BATTTEMP_ABNORMAL)) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
bool get_otg_switch(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->otg_switch;
}
}
bool oplus_chg_get_otg_online(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->otg_online;
}
}
void oplus_chg_set_otg_online(bool online)
{
if (g_charger_chip) {
g_charger_chip->otg_online = online;
}
}
bool oplus_chg_get_batt_full(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->batt_full;
}
}
bool oplus_chg_get_rechging_status(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->in_rechging;
}
}
bool oplus_chg_check_chip_is_null(void)
{
if (!g_charger_chip) {
return true;
} else {
return false;
}
}
void oplus_chg_set_charger_type_unknown(void)
{
if (g_charger_chip) {
g_charger_chip->charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
g_charger_chip->real_charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
}
}
int oplus_chg_get_charger_voltage(void)
{
if (!g_charger_chip) {
return -500;
} else {
g_charger_chip->charger_volt = g_charger_chip->chg_ops->get_charger_volt();
}
return g_charger_chip->charger_volt;
}
void oplus_chg_set_chargerid_switch_val(int value)
{
if (g_charger_chip && g_charger_chip->chg_ops->set_chargerid_switch_val) {
g_charger_chip->chg_ops->set_chargerid_switch_val(value);
}
}
void oplus_chg_clear_chargerid_info(void)
{
if (g_charger_chip && g_charger_chip->chg_ops->set_chargerid_switch_val) {
g_charger_chip->chargerid_volt = 0;
g_charger_chip->chargerid_volt_got = false;
}
}
int oplus_chg_get_cool_down_status(void)
{
int ret = 0;
struct oplus_chg_chip *chip = g_charger_chip;
if (!chip) {
return 0;
}
if (chip->smart_charge_user == SMART_CHARGE_USER_USBTEMP) {
if (chip->smart_charging_screenoff) {
chip->usbtemp_cool_down = oplus_convert_current_to_level(chip, USBTEMP_CHARGING_CURRENT_LIMIT);
} else {
chip->usbtemp_cool_down = 3;
}
if (chip->cool_down) {
ret = (chip->usbtemp_cool_down < chip->cool_down) ? chip->usbtemp_cool_down : chip->cool_down;
} else {
ret = chip->usbtemp_cool_down;
}
charger_xlog_printk(CHG_LOG_CRTI, "cool_down=%d,usbtemp_cool_down=%d\n", chip->cool_down, chip->usbtemp_cool_down);
} else {
ret = chip->cool_down;
}
return ret;
}
struct current_level {
int level;
int icharging;
};
struct current_level SVOOC_2_0[] = {
{1, 1000}, {2, 1500}, {3, 2000}, {4, 2500}, {5, 3000},
{6, 3500}, {7, 4000}, {8, 4500}, {9, 5000}, {10, 5500},
{11, 6000}, {12, 6300}, {13, 6500}, {14, 7000}, {15, 7500},
{16, 8000}, {17, 8500}, {18, 9000}, {19, 9500}, {20, 10000},
{21, 10500}, {22, 11000}, {23, 11500}, {24, 12000}, {25, 12500},
};
struct current_level SVOOC_1_0[] = {
{1, 2000}, {2, 3000}, {3, 4000}, {4, 5000}, {5, 6000},
{6, 7000}, {7, 8000}, {8, 9000}, {9, 10000}, {10, 1200},
{11, 12000}, {12, 12600}
};
int find_level_to_current(int val, struct current_level *table, int len)
{
int i = 0;
bool find_out_flag = false;
for(i = 0; i < len; i++) {
if(table[i].icharging == val) {
find_out_flag = true;
break;
}
find_out_flag = false;
}
if(find_out_flag == true) {
return table[i].level;
} else {
return 0;
}
}
int oplus_convert_current_to_level(struct oplus_chg_chip *chip, int val)
{
int level, reply_bits = 0;
reply_bits = oplus_vooc_get_reply_bits();
if(!val || !reply_bits) {
return level;
}
if(reply_bits == 7) {
if(chip->vbatt_num == 2) {
level = find_level_to_current(val, SVOOC_2_0, ARRAY_SIZE(SVOOC_2_0));
} else {
level = find_level_to_current(val, SVOOC_1_0, ARRAY_SIZE(SVOOC_1_0));
}
} else {
level = val / 1000;
}
return level;
}
#define BATT_NTC_CTRL_THRESHOLD_LOW -100
#define BATT_NTC_CTRL_THRESHOLD_HIGH 600
int oplus_chg_override_by_shell_temp(int temp)
{
if (!g_charger_chip) {
return 0;
}
if (oplus_is_power_off_charging(NULL)) {
return 0;
}
if ((g_charger_chip->charger_exist) && g_charger_chip->smart_charging_screenoff &&
(temp > BATT_NTC_CTRL_THRESHOLD_LOW) && (temp < BATT_NTC_CTRL_THRESHOLD_HIGH)) {
charger_xlog_printk(CHG_LOG_CRTI, "charging override by shell temperature\n");
return 1;
}
return 0;
}
int oplus_chg_get_shell_temp(void) {
int temp_val = 0, rc = -EINVAL;
if (!g_charger_chip) {
return TEMPERATURE_INVALID;
}
rc = thermal_zone_get_temp(g_charger_chip->shell_themal, &temp_val);
if (rc) {
chg_err("thermal_zone_get_temp get error");
return g_charger_chip->shell_temp;
}
g_charger_chip->shell_temp = temp_val / 100;
return g_charger_chip->shell_temp;
}
void oplus_smart_charge_by_shell_temp(struct oplus_chg_chip *chip, int val) {
union power_supply_propval pval = {0, };
int subtype = 0, rc = -EINVAL;
if (!chip) {
return;
}
if (chip->shell_themal) {
rc = thermal_zone_get_temp(chip->shell_themal, &chip->shell_temp);
if (rc) {
chip->shell_temp = (val >> 16) & 0XFFFF;
chg_err("thermal_zone_get_temp get error");
} else {
chip->shell_temp = chip->shell_temp / 100;
}
} else {
chip->shell_temp = (val >> 16) & 0XFFFF;
}
val = val & 0XFFFF;
charger_xlog_printk(CHG_LOG_CRTI, "val->intval = [%04x], shell_temp = [%04x], set shell_temp_down = [%d].\n", val, chip->shell_temp, chip->cool_down);
if (chip->led_on) {
return;
}
if (!val) {
if(chip->cool_down != 0){
chip->cool_down = 0;
chip->limits.input_current_charger_ma = chip->limits.default_input_current_charger_ma;
chip->limits.input_current_vooc_ma_high = chip->limits.default_input_current_vooc_ma_high;
chip->limits.input_current_vooc_ma_warm = chip->limits.default_input_current_vooc_ma_warm;
chip->limits.input_current_vooc_ma_normal = chip->limits.default_input_current_vooc_ma_normal;
chip->limits.pd_input_current_charger_ma = chip->limits.default_pd_input_current_charger_ma;
chip->limits.qc_input_current_charger_ma = chip->limits.default_qc_input_current_charger_ma;
chip->cool_down_done = true;
chip->cool_down_force_5v = false;
chip->chg_ctrl_by_cool_down = false;
}
return;
}
rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_FAST_CHG_TYPE, &pval);
if (rc < 0) {
pr_err("Failed to read charging subtype\n");
return;
}
subtype = pval.intval;
charger_xlog_printk(CHG_LOG_CRTI, "get subtype pval->intval = [%d]\n", pval.intval);
switch(pval.intval) {
case CHARGER_SUBTYPE_DEFAULT:
break;
case CHARGER_SUBTYPE_FASTCHG_VOOC:
chip->limits.input_current_vooc_ma_high = val;
chip->limits.input_current_vooc_ma_warm = val;
chip->limits.input_current_vooc_ma_normal = val;
chip->limits.input_current_cool_down_ma = val;
chip->cool_down_done = true;
chip->cool_down_force_5v = true;
chip->chg_ctrl_by_cool_down = true;
break;
case CHARGER_SUBTYPE_FASTCHG_SVOOC:
/*chip->cool_down = val / 1000;*/
/*for 7bits 25 current steps*/
chip->cool_down = oplus_convert_current_to_level(chip, val);
break;
case CHARGER_SUBTYPE_PD:
chip->limits.input_current_cool_down_ma = val;
chip->limits.pd_input_current_charger_ma = val;
chip->limits.qc_input_current_charger_ma = val;
chip->cool_down_done = true;
chip->cool_down_force_5v = false;
chip->chg_ctrl_by_cool_down = true;
break;
case CHARGER_SUBTYPE_QC:
chip->limits.input_current_cool_down_ma = val;
chip->limits.pd_input_current_charger_ma = val;
chip->limits.qc_input_current_charger_ma = val;
chip->cool_down_done = true;
chip->cool_down_force_5v = false;
chip->chg_ctrl_by_cool_down = true;
break;
default:
if (pval.intval > 10) {
chip->cool_down = oplus_convert_current_to_level(chip, val);
}
break;
}
}
static const int cool_down_current_limit_normal[6] = {500, 900, 1200, 1500, 2000, 2000};
static const int cool_down_current_limit_vooc[6] = {1000, 1500, 2000, 2500, 3000, 3500};
void oplus_smart_charge_by_cool_down(struct oplus_chg_chip *chip, int val)
{
OPLUS_CHARGER_SUBTYPE esubtype = CHARGER_SUBTYPE_DEFAULT;
if (!chip) {
return;
}
if (!val) {
chip->cool_down = 0;
esubtype = chip->chg_ops->get_charger_subtype();
if (CHARGER_SUBTYPE_PD == esubtype)
chip->limits.input_current_charger_ma = chip->limits.default_pd_input_current_charger_ma;
else if (CHARGER_SUBTYPE_QC == esubtype)
chip->limits.input_current_charger_ma = chip->limits.default_qc_input_current_charger_ma;
else
chip->limits.input_current_charger_ma = chip->limits.default_input_current_charger_ma;
chip->limits.input_current_vooc_ma_high = chip->limits.default_input_current_vooc_ma_high;
chip->limits.input_current_vooc_ma_warm = chip->limits.default_input_current_vooc_ma_warm;
chip->limits.input_current_vooc_ma_normal = chip->limits.default_input_current_vooc_ma_normal;
chip->limits.pd_input_current_charger_ma = chip->limits.default_pd_input_current_charger_ma;
chip->limits.qc_input_current_charger_ma = chip->limits.default_qc_input_current_charger_ma;
chip->cool_down_done = true;
charger_xlog_printk(CHG_LOG_CRTI, "val->intval = [%04x], set cool_down = [%d].\n", val, chip->cool_down);
return;
}
chip->cool_down = val;
if (val > 6) {
chip->limits.input_current_charger_ma = cool_down_current_limit_normal[6 - 1];
chip->limits.pd_input_current_charger_ma = cool_down_current_limit_normal[6 - 1];
chip->limits.qc_input_current_charger_ma = cool_down_current_limit_normal[6 - 1];
chip->limits.input_current_vooc_ma_high = cool_down_current_limit_vooc[6 - 1];
chip->limits.input_current_vooc_ma_warm = cool_down_current_limit_vooc[6 - 1];
chip->limits.input_current_vooc_ma_normal = cool_down_current_limit_vooc[6 - 1];
chip->cool_down_done = true;
} else {
chip->limits.input_current_charger_ma = cool_down_current_limit_normal[val - 1];
chip->limits.pd_input_current_charger_ma = cool_down_current_limit_normal[val - 1];
chip->limits.qc_input_current_charger_ma = cool_down_current_limit_normal[val - 1];
chip->limits.input_current_vooc_ma_high = cool_down_current_limit_vooc[val - 1];
chip->limits.input_current_vooc_ma_warm = cool_down_current_limit_vooc[val - 1];
chip->limits.input_current_vooc_ma_normal = cool_down_current_limit_vooc[val - 1];
chip->cool_down_done = true;
}
charger_xlog_printk(CHG_LOG_CRTI, "val->intval = [%04x], set cool_down = [%d].\n", val, chip->cool_down);
}
int oplus_is_rf_ftm_mode(void)
{
int boot_mode = get_boot_mode();
#ifdef CONFIG_OPLUS_CHARGER_MTK
if (boot_mode == META_BOOT || boot_mode == FACTORY_BOOT
|| boot_mode == ADVMETA_BOOT || boot_mode == ATE_FACTORY_BOOT) {
chg_debug(" boot_mode:%d, return\n",boot_mode);
return true;
} else {
chg_debug(" boot_mode:%d, return false\n",boot_mode);
return false;
}
#else
if(boot_mode == MSM_BOOT_MODE__RF || boot_mode == MSM_BOOT_MODE__WLAN
|| boot_mode == MSM_BOOT_MODE__FACTORY){
chg_debug(" boot_mode:%d, return\n",boot_mode);
return true;
} else {
chg_debug(" boot_mode:%d, return false\n",boot_mode);
return false;
}
#endif
}
#ifdef CONFIG_OPLUS_CHARGER_MTK
/*
int get_oplus_short_check_fast_to_normal(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->short_check_fast_to_normal_flag;
}
}
*/
int oplus_get_prop_status(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->prop_status;
}
}
#endif
#define OPLUS_TBATT_HIGH_PWROFF_COUNT (18)
#define OPLUS_TBATT_EMERGENCY_PWROFF_COUNT (6)
DECLARE_WAIT_QUEUE_HEAD(oplus_tbatt_pwroff_wq);
static int oplus_tbatt_power_off_kthread(void *arg)
{
int over_temp_count = 0, emergency_count = 0;
int batt_temp = 0;
//struct oplus_chg_chip *chip = (struct oplus_chg_chip *)arg;
struct sched_param param = {.sched_priority = MAX_RT_PRIO-1};
sched_setscheduler(current, SCHED_FIFO, &param);
tbatt_pwroff_enable = 1;
while (!kthread_should_stop()) {
schedule_timeout_interruptible(round_jiffies_relative(msecs_to_jiffies(5*1000)));
//chg_err(" tbatt_pwroff_enable:%d over_temp_count[%d] start\n", tbatt_pwroff_enable, over_temp_count);
if (!tbatt_pwroff_enable) {
emergency_count = 0;
over_temp_count = 0;
wait_event_interruptible(oplus_tbatt_pwroff_wq, tbatt_pwroff_enable == 1);
}
if (oplus_vooc_get_fastchg_started() == true) {
batt_temp = oplus_gauge_get_prev_batt_temperature();
} else {
batt_temp = oplus_gauge_get_batt_temperature();
}
if (batt_temp > OPCHG_PWROFF_EMERGENCY_BATT_TEMP) {
emergency_count++;
chg_err(" emergency_count:%d \n", emergency_count);
} else {
emergency_count = 0;
}
if (batt_temp > OPCHG_PWROFF_HIGH_BATT_TEMP) {
over_temp_count++;
chg_err("over_temp_count[%d] \n", over_temp_count);
} else {
over_temp_count = 0;
}
//chg_err("over_temp_count[%d], chip->temperature[%d]\n", over_temp_count, batt_temp);
if (get_eng_version() != HIGH_TEMP_AGING) {
if (over_temp_count >= OPLUS_TBATT_HIGH_PWROFF_COUNT
|| emergency_count >= OPLUS_TBATT_EMERGENCY_PWROFF_COUNT) {
chg_err("ERROR: battery temperature is too high, goto power off\n");
/*msleep(1000);*/
machine_power_off();
}
}
}
return 0;
}
int oplus_tbatt_power_off_task_init(struct oplus_chg_chip *chip)
{
if (!chip) {
return -1;
}
chip->tbatt_pwroff_task
= kthread_create(oplus_tbatt_power_off_kthread, chip, "tbatt_pwroff");
if(chip->tbatt_pwroff_task){
wake_up_process(chip->tbatt_pwroff_task);
}else{
chg_err("ERROR: chip->tbatt_pwroff_task creat fail\n");
return -1;
}
return 0;
}
void oplus_tbatt_power_off_task_wakeup(void)
{
wake_up_interruptible(&oplus_tbatt_pwroff_wq);
return;
}
bool oplus_get_chg_powersave(void)
{
if (!g_charger_chip) {
return false;
} else {
return g_charger_chip->chg_powersave;
}
}
int oplus_get_chg_unwakelock(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->unwakelock_chg;
}
}
bool oplus_get_vbatt_higherthan_xmv(void)
{
if (!g_charger_chip) {
return false;
} else {
return vbatt_higherthan_4180mv;
}
}
void oplus_chg_set_input_current_without_aicl(int current_ma)
{
if (!g_charger_chip) {
return ;
} else {
if(g_charger_chip->chg_ops->input_current_write_without_aicl && oplus_vooc_get_allow_reading() == true) {
g_charger_chip->chg_ops->input_current_write_without_aicl(current_ma);
chg_err("current_ma[%d]\n", current_ma);
}
}
}
void oplus_chg_config_charger_vsys_threshold(int val)
{
if (!g_charger_chip) {
return ;
} else {
if(g_charger_chip->chg_ops->set_charger_vsys_threshold && oplus_vooc_get_allow_reading() == true) {
g_charger_chip->chg_ops->set_charger_vsys_threshold(val);
chg_err("set val[%d]\n", val);
}
}
}
void oplus_chg_enable_burst_mode(bool enable)
{
if (!g_charger_chip) {
return ;
} else {
if(g_charger_chip->chg_ops->enable_burst_mode && oplus_vooc_get_allow_reading() == true) {
g_charger_chip->chg_ops->enable_burst_mode(enable);
chg_err("set val[%d]\n", enable);
}
}
}
int oplus_chg_get_tbatt_status(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->tbatt_status;
}
}
int oplus_chg_match_temp_for_chging(void)
{
int batt_temp = 0;
int shell_temp = 0;
int diff = 0;
int chging_temp = 0;
if (!g_charger_chip) {
return chging_temp;
}
if (oplus_vooc_get_fastchg_started() == true) {
batt_temp = oplus_gauge_get_prev_batt_temperature();
} else {
batt_temp = oplus_gauge_get_batt_temperature();
}
if (oplus_chg_override_by_shell_temp(batt_temp)) {
shell_temp = oplus_chg_get_shell_temp();
diff = shell_temp - batt_temp;
if(diff < 150 && diff > -150 && batt_temp >= 320) {
chging_temp = shell_temp;
} else {
chging_temp = batt_temp;
}
} else {
chging_temp = batt_temp;
}
g_charger_chip->tbatt_temp = batt_temp;
return chging_temp;
}
bool opchg_get_shipmode_value(void)
{
if (!g_charger_chip) {
return 0;
} else {
return g_charger_chip->enable_shipmode;
}
}