kernel_samsung_a34x-permissive/drivers/power/supply/mtk_battery_daemon.c

4657 lines
104 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019 MediaTek Inc.
* Author Wy Chuang<wy.chuang@mediatek.com>
*/
#include <linux/netlink.h> /* netlink */
#ifdef CONFIG_OF
#include <linux/of_fdt.h> /*of_dt API*/
#endif
#include <linux/platform_device.h>
#include <linux/reboot.h> /*kernel_power_off*/
#include <linux/skbuff.h> /* netlink */
#include <linux/socket.h> /* netlink */
#include <net/sock.h> /* netlink */
#include "mtk_battery_daemon.h"
#include "mtk_battery.h"
#if IS_ENABLED(CONFIG_PMIC_LBAT_SERVICE)
#include <pmic_lbat_service.h>
#endif
static int interpolation(int i1, int b1, int i2, int b2, int i)
{
int ret;
ret = (b2 - b1) * (i - i1) / (i2 - i1) + b1;
return ret;
}
/* ============================================================ */
/* Customized function */
/* ============================================================ */
int get_customized_aging_factor(int orig_af)
{
return (orig_af + 100);
}
int get_customized_d0_c_soc(int origin_d0_c_soc)
{
int val;
val = (origin_d0_c_soc + 0);
return val;
}
int get_customized_d0_v_soc(int origin_d0_v_soc)
{
int val;
val = (origin_d0_v_soc + 0);
return val;
}
int get_customized_uisoc(int origin_uisoc)
{
int val;
val = (origin_uisoc + 0);
return val;
}
int fg_get_system_sec(void)
{
struct timespec time;
time.tv_sec = 0;
time.tv_nsec = 0;
get_monotonic_boottime(&time);
return (int)time.tv_sec;
}
int fg_get_imix(void)
{
/* todo: in ALPS */
return 1;
}
int gauge_set_nag_en(struct mtk_battery *gm, int nafg_zcv_en)
{
if (gm->disableGM30)
return 0;
if (gm->disable_nafg_int == false)
gauge_set_property(GAUGE_PROP_NAFG_EN, nafg_zcv_en);
bm_debug(
"%s = %d\n",
__func__,
nafg_zcv_en);
return 0;
}
int gauge_get_average_current(struct mtk_battery *gm, bool *valid)
{
int iavg = 0;
int ver;
ver = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
if (gm->disableGM30)
iavg = 0;
else {
if (ver >= GAUGE_HW_V1000 &&
ver < GAUGE_HW_V2000)
iavg = gm->sw_iavg;
else {
*valid = gm->gauge->fg_hw_info.current_avg_valid;
iavg =
gauge_get_int_property(GAUGE_PROP_AVERAGE_CURRENT);
}
}
return iavg;
}
void mtk_battery_send_to_user(struct mtk_battery *gm,
int seq, struct fgd_nl_msg_t *reply_msg)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
u32 pid = 0;
int size = reply_msg->fgd_data_len + FGD_NL_HDR_LEN;
int len = NLMSG_SPACE(size);
void *data;
int ret = -1;
if (gm == NULL)
gm = get_mtk_battery();
if (gm != NULL)
pid = gm->fgd_pid;
reply_msg->identity = FGD_NL_MAGIC;
if (in_interrupt())
skb = alloc_skb(len, GFP_ATOMIC);
else
skb = alloc_skb(len, GFP_KERNEL);
if (!skb)
return;
nlh = nlmsg_put(skb, pid, seq, 0, size, 0);
data = NLMSG_DATA(nlh);
memcpy(data, reply_msg, size);
NETLINK_CB(skb).portid = 0; /* from kernel */
NETLINK_CB(skb).dst_group = 0; /* unicast */
if (gm->mtk_battery_sk != NULL)
ret = netlink_unicast
(gm->mtk_battery_sk, skb, pid, MSG_DONTWAIT);
if (ret < 0) {
bm_err("[%s]send failed ret=%d pid=%d\n", __func__, ret, pid);
return;
}
}
void fg_cmd_check(struct fgd_nl_msg_t *msg)
{
while (msg->fgd_subcmd == 0 &&
msg->fgd_subcmd_para1 != FGD_NL_HDR_LEN) {
bm_err("fuel gauge version error cmd:%d %d\n",
msg->fgd_cmd,
msg->fgd_subcmd);
msleep(10000);
break;
}
}
void fg_daemon_send_data(struct mtk_battery *gm,
int cmd, char *rcv, char *ret)
{
struct fgd_cmd_param_t_4 *prcv;
struct fgd_cmd_param_t_4 *pret;
prcv = (struct fgd_cmd_param_t_4 *)rcv;
pret = (struct fgd_cmd_param_t_4 *)ret;
bm_debug("%s type:%d, tsize:%d size:%d idx:%d\n",
__func__,
cmd,
prcv->total_size,
prcv->size,
prcv->idx);
pret->total_size = prcv->total_size;
pret->size = prcv->size;
pret->idx = prcv->idx;
switch (cmd) {
case FG_DAEMON_CMD_SEND_CUSTOM_TABLE:
{
char *ptr;
if (sizeof(struct fgd_cmd_param_t_custom)
!= prcv->total_size) {
bm_err("%s size is different %d %d\n",
__func__,
(int)sizeof(
struct fgd_cmd_param_t_custom),
prcv->total_size);
}
ptr = (char *)&gm->fg_data;
memcpy(&ptr[prcv->idx],
prcv->input,
prcv->size);
bm_debug(
"FG_DATA_TYPE_TABLE type:%d size:%d %d idx:%d\n",
FG_DAEMON_CMD_SEND_CUSTOM_TABLE,
prcv->total_size,
prcv->size,
prcv->idx);
}
break;
default:
bm_err("%s bad cmd 0x%x\n",
__func__, cmd);
break;
}
}
void fg_daemon_get_data(int cmd,
char *rcv,
char *ret)
{
struct fgd_cmd_param_t_4 *prcv;
struct fgd_cmd_param_t_4 *pret;
struct mtk_battery *gm;
gm = get_mtk_battery();
prcv = (struct fgd_cmd_param_t_4 *)rcv;
pret = (struct fgd_cmd_param_t_4 *)ret;
bm_debug("%s type:%d, tsize:%d size:%d idx:%d\n",
__func__,
cmd,
prcv->total_size,
prcv->size,
prcv->idx);
pret->total_size = prcv->total_size;
pret->size = prcv->size;
pret->idx = prcv->idx;
switch (cmd) {
case FG_DAEMON_CMD_GET_CUSTOM_SETTING:
{
char *ptr;
if (sizeof(struct fuel_gauge_custom_data)
!= prcv->total_size) {
bm_err("%s size is different %d %d\n",
__func__,
(int)sizeof(
struct fuel_gauge_custom_data),
prcv->total_size);
}
ptr = (char *)&gm->fg_cust_data;
memcpy(pret->input, &ptr[prcv->idx], pret->size);
bm_trace(
"FG_DATA_TYPE_TABLE type:%d size:%d %d idx:%d data:%d %d %d %d\n",
FG_DAEMON_CMD_GET_CUSTOM_SETTING,
pret->total_size,
pret->size,
pret->idx,
pret->input[0],
pret->input[1],
pret->input[2],
pret->input[3]);
}
break;
case FG_DAEMON_CMD_GET_CUSTOM_TABLE:
{
char *ptr;
if (sizeof(struct fuel_gauge_table_custom_data)
!= prcv->total_size) {
bm_err("%s size is different %d %d\n",
__func__,
(int)sizeof(
struct fuel_gauge_table_custom_data),
prcv->total_size);
}
ptr = (char *)&gm->fg_table_cust_data;
memcpy(pret->input, &ptr[prcv->idx],
pret->size);
bm_trace(
"FG_DATA_TYPE_TABLE type:%d size:%d %d idx:%d\n",
FG_DAEMON_CMD_GET_CUSTOM_TABLE,
prcv->total_size,
prcv->size,
prcv->idx);
}
break;
default:
bm_err("%s bad cmd:0x%x\n",
__func__, cmd);
break;
}
}
void fg_ocv_query_soc(struct mtk_battery *gm, int ocv)
{
if (ocv > 50000 || ocv <= 0)
return;
gm->algo_req_ocv = ocv;
wakeup_fg_algo_cmd(gm,
FG_INTR_KERNEL_CMD, FG_KERNEL_CMD_REQ_ALGO_DATA,
ocv);
bm_trace("[%s] ocv:%d\n",
__func__, ocv);
}
void fg_custom_data_check(struct mtk_battery *gm)
{
struct fuel_gauge_custom_data *p;
struct fuel_gauge_table_custom_data *fg_table_cust_data;
p = &gm->fg_cust_data;
fg_table_cust_data = &gm->fg_table_cust_data;
fgauge_get_profile_id();
bm_err("FGLOG MultiGauge0[%d] BATID[%d] pmic_min_vol[%d,%d,%d,%d,%d]\n",
p->multi_temp_gauge0, gm->battery_id,
fg_table_cust_data->fg_profile[0].pmic_min_vol,
fg_table_cust_data->fg_profile[1].pmic_min_vol,
fg_table_cust_data->fg_profile[2].pmic_min_vol,
fg_table_cust_data->fg_profile[3].pmic_min_vol,
fg_table_cust_data->fg_profile[4].pmic_min_vol);
bm_err("FGLOG pon_iboot[%d,%d,%d,%d,%d] qmax_sys_vol[%d %d %d %d %d]\n",
fg_table_cust_data->fg_profile[0].pon_iboot,
fg_table_cust_data->fg_profile[1].pon_iboot,
fg_table_cust_data->fg_profile[2].pon_iboot,
fg_table_cust_data->fg_profile[3].pon_iboot,
fg_table_cust_data->fg_profile[4].pon_iboot,
fg_table_cust_data->fg_profile[0].qmax_sys_vol,
fg_table_cust_data->fg_profile[1].qmax_sys_vol,
fg_table_cust_data->fg_profile[2].qmax_sys_vol,
fg_table_cust_data->fg_profile[3].qmax_sys_vol,
fg_table_cust_data->fg_profile[4].qmax_sys_vol);
}
void Intr_Number_to_Name(char *intr_name, unsigned int intr_no)
{
switch (intr_no) {
case FG_INTR_0:
sprintf(intr_name, "FG_INTR_INIT");
break;
case FG_INTR_TIMER_UPDATE:
sprintf(intr_name, "FG_INTR_TIMER_UPDATE");
break;
case FG_INTR_BAT_CYCLE:
sprintf(intr_name, "FG_INTR_BAT_CYCLE");
break;
case FG_INTR_CHARGER_OUT:
sprintf(intr_name, "FG_INTR_CHARGER_OUT");
break;
case FG_INTR_CHARGER_IN:
sprintf(intr_name, "FG_INTR_CHARGER_IN");
break;
case FG_INTR_FG_TIME:
sprintf(intr_name, "FG_INTR_FG_TIME");
break;
case FG_INTR_BAT_INT1_HT:
sprintf(intr_name, "FG_INTR_COULOMB_HT");
break;
case FG_INTR_BAT_INT1_LT:
sprintf(intr_name, "FG_INTR_COULOMB_LT");
break;
case FG_INTR_BAT_INT2_HT:
sprintf(intr_name, "FG_INTR_UISOC_HT");
break;
case FG_INTR_BAT_INT2_LT:
sprintf(intr_name, "FG_INTR_UISOC_LT");
break;
case FG_INTR_BAT_TMP_HT:
sprintf(intr_name, "FG_INTR_BAT_TEMP_HT");
break;
case FG_INTR_BAT_TMP_LT:
sprintf(intr_name, "FG_INTR_BAT_TEMP_LT");
break;
case FG_INTR_BAT_TIME_INT:
sprintf(intr_name, "FG_INTR_BAT_TIME_INT");
break;
case FG_INTR_NAG_C_DLTV:
sprintf(intr_name, "FG_INTR_NAFG_VOLTAGE");
break;
case FG_INTR_FG_ZCV:
sprintf(intr_name, "FG_INTR_FG_ZCV");
break;
case FG_INTR_SHUTDOWN:
sprintf(intr_name, "FG_INTR_SHUTDOWN");
break;
case FG_INTR_RESET_NVRAM:
sprintf(intr_name, "FG_INTR_RESET_NVRAM");
break;
case FG_INTR_BAT_PLUGOUT:
sprintf(intr_name, "FG_INTR_BAT_PLUGOUT");
break;
case FG_INTR_IAVG:
sprintf(intr_name, "FG_INTR_IAVG");
break;
case FG_INTR_VBAT2_L:
sprintf(intr_name, "FG_INTR_VBAT2_L");
break;
case FG_INTR_VBAT2_H:
sprintf(intr_name, "FG_INTR_VBAT2_H");
break;
case FG_INTR_CHR_FULL:
sprintf(intr_name, "FG_INTR_CHR_FULL");
break;
case FG_INTR_DLPT_SD:
sprintf(intr_name, "FG_INTR_DLPT_SD");
break;
case FG_INTR_BAT_TMP_C_HT:
sprintf(intr_name, "FG_INTR_BAT_TMP_C_HT");
break;
case FG_INTR_BAT_TMP_C_LT:
sprintf(intr_name, "FG_INTR_BAT_TMP_C_LT");
break;
case FG_INTR_BAT_INT1_CHECK:
sprintf(intr_name, "FG_INTR_COULOMB_C");
break;
case FG_INTR_KERNEL_CMD:
sprintf(intr_name, "FG_INTR_KERNEL_CMD");
break;
case FG_INTR_BAT_INT2_CHECK:
sprintf(intr_name, "FG_INTR_BAT_INT2_CHECK");
break;
default:
sprintf(intr_name, "FG_INTR_UNKNOWN");
bm_err("[%s] unknown intr %d\n", __func__, intr_no);
break;
}
}
void exec_BAT_EC(int cmd, int param)
{
int i;
struct mtk_battery *gm;
struct BAT_EC_Struct *ec;
struct fuel_gauge_custom_data *fg_cust_data;
struct fuel_gauge_table_custom_data *fg_table_cust_data;
gm = get_mtk_battery();
ec = &gm->Bat_EC_ctrl;
fg_cust_data = &gm->fg_cust_data;
fg_table_cust_data = &gm->fg_table_cust_data;
bm_err("exe_BAT_EC cmd %d, param %d\n", cmd, param);
switch (cmd) {
case 101:
{
/* Force Temperature, force_get_tbat*/
if (param == 0xff) {
ec->fixed_temp_en = 0;
ec->fixed_temp_value = 25;
bm_err("exe_BAT_EC cmd %d, param %d, disable\n",
cmd, param);
} else {
ec->fixed_temp_en = 1;
if (param >= 100)
ec->fixed_temp_value =
0 - (param - 100);
else
ec->fixed_temp_value = param;
bm_err("exe_BAT_EC cmd %d, param %d, enable\n",
cmd, param);
}
}
break;
case 105:
{
/* force interrupt trigger */
switch (param) {
case 1:
{
wakeup_fg_algo(gm,
FG_INTR_TIMER_UPDATE);
}
break;
case 4096:
{
wakeup_fg_algo(gm, FG_INTR_NAG_C_DLTV);
}
break;
case 8192:
{
wakeup_fg_algo(gm, FG_INTR_FG_ZCV);
}
break;
case 32768:
{
wakeup_fg_algo(gm, FG_INTR_RESET_NVRAM);
}
break;
case 65536:
{
wakeup_fg_algo(gm, FG_INTR_BAT_PLUGOUT);
}
break;
default:
{
}
break;
}
bm_err(
"exe_BAT_EC cmd %d, param %d, force interrupt\n",
cmd, param);
}
break;
case 108:
{
/* Set D0_C_CUST */
if (param == 0xff) {
ec->debug_d0_c_en = 0;
ec->debug_d0_c_value = 0;
bm_err(
"exe_BAT_EC cmd %d, param %d, disable\n",
cmd, param);
} else {
ec->debug_d0_c_en = 1;
ec->debug_d0_c_value = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, enable\n",
cmd, param);
}
}
break;
case 109:
{
/* Set D0_V_CUST */
if (param == 0xff) {
ec->debug_d0_v_en = 0;
ec->debug_d0_v_value = 0;
bm_err(
"exe_BAT_EC cmd %d, param %d, disable\n",
cmd, param);
} else {
ec->debug_d0_v_en = 1;
ec->debug_d0_v_value = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, enable\n",
cmd, param);
}
}
break;
case 110:
{
/* Set UISOC_CUST */
if (param == 0xff) {
ec->debug_uisoc_en = 0;
ec->debug_uisoc_value = 0;
bm_err(
"exe_BAT_EC cmd %d, param %d, disable\n",
cmd, param);
} else {
ec->debug_uisoc_en = 1;
ec->debug_uisoc_value = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, enable\n",
cmd, param);
}
}
break;
case 701:
{
fg_cust_data->pseudo1_en = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, pseudo1_en\n",
cmd, param);
}
break;
case 702:
{
fg_cust_data->pseudo100_en = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, pseudo100_en\n",
cmd, param);
}
break;
case 703:
{
fg_cust_data->qmax_sel = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, qmax_sel\n",
cmd, param);
}
break;
case 704:
{
fg_cust_data->iboot_sel = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, iboot_sel\n",
cmd, param);
}
break;
case 705:
{
for (i = 0;
i < fg_table_cust_data->active_table_number;
i++) {
fg_table_cust_data->fg_profile[i].pmic_min_vol =
param * UNIT_TRANS_10;
}
bm_err(
"exe_BAT_EC cmd %d, param %d, pmic_min_vol\n",
cmd, param);
}
break;
case 706:
{
for (i = 0;
i < fg_table_cust_data->active_table_number;
i++) {
fg_table_cust_data->fg_profile[i].pon_iboot =
param * UNIT_TRANS_10;
}
bm_err("exe_BAT_EC cmd %d, param %d, poweron_system_iboot\n"
, cmd, param * UNIT_TRANS_10);
}
break;
case 707:
{
fg_cust_data->shutdown_system_iboot = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, shutdown_system_iboot\n",
cmd, param);
}
break;
case 708:
{
fg_cust_data->com_fg_meter_resistance = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, com_fg_meter_resistance\n",
cmd, param);
}
break;
case 709:
{
fg_cust_data->r_fg_value = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, r_fg_value\n",
cmd, param);
}
break;
case 710:
{
fg_cust_data->q_max_sys_voltage = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, q_max_sys_voltage\n",
cmd, param);
}
break;
case 711:
{
fg_cust_data->loading_1_en = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, loading_1_en\n",
cmd, param);
}
break;
case 712:
{
fg_cust_data->loading_2_en = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, loading_2_en\n",
cmd, param);
}
break;
case 713:
{
fg_cust_data->aging_temp_diff = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, aging_temp_diff\n",
cmd, param);
}
break;
case 714:
{
fg_cust_data->aging1_load_soc = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, aging1_load_soc\n",
cmd, param);
}
break;
case 715:
{
fg_cust_data->aging1_update_soc = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, aging1_update_soc\n",
cmd, param);
}
break;
case 716:
{
fg_cust_data->aging_100_en = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, aging_100_en\n",
cmd, param);
}
break;
case 717:
{
fg_table_cust_data->active_table_number = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, additional_battery_table_en\n",
cmd, param);
}
break;
case 718:
{
fg_cust_data->d0_sel = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, d0_sel\n",
cmd, param);
}
break;
case 719:
{
fg_cust_data->zcv_car_gap_percentage = param;
bm_err(
"exe_BAT_EC cmd %d, param %d, zcv_car_gap_percentage\n",
cmd, param);
}
break;
case 720:
{
fg_cust_data->multi_temp_gauge0 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->multi_temp_gauge0=%d\n",
cmd, param);
}
break;
case 721:
{
fg_custom_data_check(gm);
bm_err("exe_BAT_EC cmd %d", cmd);
}
break;
case 724:
{
fg_table_cust_data->fg_profile[0].pseudo100 =
UNIT_TRANS_100 * param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pseudo100_t0=%d\n",
cmd, param);
}
break;
case 725:
{
fg_table_cust_data->fg_profile[1].pseudo100 =
UNIT_TRANS_100 * param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pseudo100_t1=%d\n",
cmd, param);
}
break;
case 726:
{
fg_table_cust_data->fg_profile[2].pseudo100 =
UNIT_TRANS_100 * param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pseudo100_t2=%d\n",
cmd, param);
}
break;
case 727:
{
fg_table_cust_data->fg_profile[3].pseudo100 =
UNIT_TRANS_100 * param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pseudo100_t3=%d\n",
cmd, param);
}
break;
case 728:
{
fg_table_cust_data->fg_profile[4].pseudo100 =
UNIT_TRANS_100 * param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pseudo100_t4=%d\n",
cmd, param);
}
break;
case 729:
{
fg_cust_data->keep_100_percent = UNIT_TRANS_100 * param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->keep_100_percent=%d\n",
cmd, param);
}
break;
case 730:
{
fg_cust_data->ui_full_limit_en = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_en=%d\n",
cmd, param);
}
break;
case 731:
{
fg_cust_data->ui_full_limit_soc0 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_soc0=%d\n",
cmd, param);
}
break;
case 732:
{
fg_cust_data->ui_full_limit_ith0 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_ith0=%d\n",
cmd, param);
}
break;
case 733:
{
fg_cust_data->ui_full_limit_soc1 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_soc1=%d\n",
cmd, param);
}
break;
case 734:
{
fg_cust_data->ui_full_limit_ith1 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_ith1=%d\n",
cmd, param);
}
break;
case 735:
{
fg_cust_data->ui_full_limit_soc2 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_soc2=%d\n",
cmd, param);
}
break;
case 736:
{
fg_cust_data->ui_full_limit_ith2 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_ith2=%d\n",
cmd, param);
}
break;
case 737:
{
fg_cust_data->ui_full_limit_soc3 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_soc3=%d\n",
cmd, param);
}
break;
case 738:
{
fg_cust_data->ui_full_limit_ith3 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_ith3=%d\n",
cmd, param);
}
break;
case 739:
{
fg_cust_data->ui_full_limit_soc4 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_soc4=%d\n",
cmd, param);
}
break;
case 740:
{
fg_cust_data->ui_full_limit_ith4 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_ith4=%d\n",
cmd, param);
}
break;
case 741:
{
fg_cust_data->ui_full_limit_time = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->ui_full_limit_time=%d\n",
cmd, param);
}
break;
case 743:
{
fg_table_cust_data->fg_profile[0].pmic_min_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pmic_min_vol_t0=%d\n",
cmd, param);
}
break;
case 744:
{
fg_table_cust_data->fg_profile[1].pmic_min_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pmic_min_vol_t1=%d\n",
cmd, param);
}
break;
case 745:
{
fg_table_cust_data->fg_profile[2].pmic_min_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pmic_min_vol_t2=%d\n",
cmd, param);
}
break;
case 746:
{
fg_table_cust_data->fg_profile[3].pmic_min_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pmic_min_vol_t3=%d\n",
cmd, param);
}
break;
case 747:
{
fg_table_cust_data->fg_profile[4].pmic_min_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pmic_min_vol_t4=%d\n",
cmd, param);
}
break;
case 748:
{
fg_table_cust_data->fg_profile[0].pon_iboot = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pon_iboot_t0=%d\n",
cmd, param);
}
break;
case 749:
{
fg_table_cust_data->fg_profile[1].pon_iboot = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pon_iboot_t1=%d\n",
cmd, param);
}
break;
case 750:
{
fg_table_cust_data->fg_profile[2].pon_iboot = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pon_iboot_t2=%d\n",
cmd, param);
}
break;
case 751:
{
fg_table_cust_data->fg_profile[3].pon_iboot = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pon_iboot_t3=%d\n",
cmd, param);
}
break;
case 752:
{
fg_table_cust_data->fg_profile[4].pon_iboot = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->pon_iboot_t4=%d\n",
cmd, param);
}
break;
case 753:
{
fg_table_cust_data->fg_profile[0].qmax_sys_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->qmax_sys_vol_t0=%d\n",
cmd, param);
}
break;
case 754:
{
fg_table_cust_data->fg_profile[1].qmax_sys_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->qmax_sys_vol_t1=%d\n",
cmd, param);
}
break;
case 755:
{
fg_table_cust_data->fg_profile[2].qmax_sys_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->qmax_sys_vol_t2=%d\n",
cmd, param);
}
break;
case 756:
{
fg_table_cust_data->fg_profile[3].qmax_sys_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->qmax_sys_vol_t3=%d\n",
cmd, param);
}
break;
case 757:
{
fg_table_cust_data->fg_profile[4].qmax_sys_vol = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->qmax_sys_vol_t4=%d\n",
cmd, param);
}
break;
case 758:
{
fg_cust_data->nafg_ratio = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->nafg_ratio=%d\n",
cmd, param);
}
break;
case 759:
{
fg_cust_data->nafg_ratio_en = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->nafg_ratio_en=%d\n",
cmd, param);
}
break;
case 760:
{
fg_cust_data->nafg_ratio_tmp_thr = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->nafg_ratio_tmp_thr=%d\n",
cmd, param);
}
break;
case 761:
{
wakeup_fg_algo(gm, FG_INTR_BAT_CYCLE);
bm_err(
"exe_BAT_EC cmd %d, bat_cycle intr\n", cmd);
}
break;
case 762:
{
fg_cust_data->difference_fgc_fgv_th1 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->difference_fgc_fgv_th1=%d\n",
cmd, param);
}
break;
case 763:
{
fg_cust_data->difference_fgc_fgv_th2 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->difference_fgc_fgv_th1=%d\n",
cmd, param);
}
break;
case 764:
{
fg_cust_data->difference_fgc_fgv_th3 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->difference_fgc_fgv_th3=%d\n",
cmd, param);
}
break;
case 765:
{
fg_cust_data->difference_fullocv_ith = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->difference_fullocv_ith=%d\n",
cmd, param);
}
break;
case 766:
{
fg_cust_data->difference_fgc_fgv_th_soc1 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->difference_fgc_fgv_th_soc1=%d\n",
cmd, param);
}
break;
case 767:
{
fg_cust_data->difference_fgc_fgv_th_soc2 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->difference_fgc_fgv_th_soc2=%d\n",
cmd, param);
}
break;
case 768:
{
fg_cust_data->embedded_sel = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->embedded_sel=%d\n",
cmd, param);
}
break;
case 769:
{
fg_cust_data->car_tune_value = param * UNIT_TRANS_10;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->car_tune_value=%d\n",
cmd, param * UNIT_TRANS_10);
}
break;
case 770:
{
fg_cust_data->shutdown_1_time = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->shutdown_1_time=%d\n",
cmd, param);
}
break;
case 771:
{
fg_cust_data->tnew_told_pon_diff = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->tnew_told_pon_diff=%d\n",
cmd, param);
}
break;
case 772:
{
fg_cust_data->tnew_told_pon_diff2 = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->tnew_told_pon_diff2=%d\n",
cmd, param);
}
break;
case 773:
{
fg_cust_data->swocv_oldocv_diff = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->swocv_oldocv_diff=%d\n",
cmd, param);
}
break;
case 774:
{
fg_cust_data->hwocv_oldocv_diff = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->hwocv_oldocv_diff=%d\n",
cmd, param);
}
break;
case 775:
{
fg_cust_data->hwocv_swocv_diff = param;
bm_err(
"exe_BAT_EC cmd %d, fg_cust_data->hwocv_swocv_diff=%d\n",
cmd, param);
}
break;
case 776:
{
ec->debug_kill_daemontest = param;
bm_err(
"exe_BAT_EC cmd %d, debug_kill_daemontest=%d\n",
cmd, param);
}
break;
case 777:
{
fg_cust_data->swocv_oldocv_diff_emb = param;
bm_err("exe_BAT_EC cmd %d, swocv_oldocv_diff_emb=%d\n",
cmd, param);
}
break;
case 778:
{
fg_cust_data->vir_oldocv_diff_emb_lt = param;
bm_err(
"exe_BAT_EC cmd %d, vir_oldocv_diff_emb_lt=%d\n",
cmd, param);
}
break;
case 779:
{
fg_cust_data->vir_oldocv_diff_emb_tmp = param;
bm_err(
"exe_BAT_EC cmd %d, vir_oldocv_diff_emb_tmp=%d\n",
cmd, param);
}
break;
case 780:
{
fg_cust_data->vir_oldocv_diff_emb = param;
bm_err("exe_BAT_EC cmd %d, vir_oldocv_diff_emb=%d\n",
cmd, param);
}
break;
case 781:
{
ec->debug_kill_daemontest = 1;
fg_cust_data->dod_init_sel = 12;
bm_err("exe_BAT_EC cmd %d,force goto dod_init12=%d\n",
cmd, param);
}
break;
case 782:
{
fg_cust_data->charge_pseudo_full_level = param;
bm_err(
"exe_BAT_EC cmd %d,fg_cust_data->charge_pseudo_full_level=%d\n",
cmd, param);
}
break;
case 783:
{
fg_cust_data->full_tracking_bat_int2_multiply = param;
bm_err(
"exe_BAT_EC cmd %d,fg_cust_data->full_tracking_bat_int2_multiply=%d\n",
cmd, param);
}
break;
case 784:
{
bm_err(
"exe_BAT_EC cmd %d,DAEMON_PID=%d\n",
cmd, gm->fgd_pid);
}
break;
case 785:
{
gm->bat_cycle_thr = param;
bm_err(
"exe_BAT_EC cmd %d,thr=%d\n",
cmd, gm->bat_cycle_thr);
}
break;
case 786:
{
gm->bat_cycle_ncar = param;
bm_err(
"exe_BAT_EC cmd %d,thr=%d\n",
cmd, gm->bat_cycle_ncar);
}
break;
case 787:
{
fg_ocv_query_soc(gm, param);
bm_err(
"exe_BAT_EC cmd %d,[fg_ocv_query_soc]ocv=%d\n",
cmd, param);
}
break;
case 788:
{
fg_cust_data->record_log = param;
bm_err(
"exe_BAT_EC cmd %d,record_log=%d\n",
cmd, fg_cust_data->record_log);
}
break;
case 789:
{
int zcv_avg_current = 0;
zcv_avg_current = param;
gauge_set_property(GAUGE_PROP_ZCV_INTR_EN, 0);
gauge_set_property(GAUGE_PROP_ZCV_INTR_THRESHOLD,
zcv_avg_current);
gauge_set_property(GAUGE_PROP_ZCV_INTR_EN, 1);
bm_err(
"exe_BAT_EC cmd %d,zcv_avg_current =%d\n",
cmd, param);
}
break;
case 790:
{
bm_err(
"exe_BAT_EC cmd %d,force DLPT shutdown", cmd);
wakeup_fg_algo(gm, FG_INTR_DLPT_SD);
}
break;
case 791:
{
gm->enable_tmp_intr_suspend = param;
bm_err(
"exe_BAT_EC cmd %d,gm->enable_tmp_intr_suspend =%d\n",
cmd, param);
}
break;
case 792:
{
wakeup_fg_algo_cmd(gm,
FG_INTR_KERNEL_CMD,
FG_KERNEL_CMD_BUILD_SEL_BATTEMP,
param);
bm_err(
"exe_BAT_EC cmd %d,req bat table temp =%d\n",
cmd, param);
}
break;
case 793:
{
wakeup_fg_algo_cmd(gm,
FG_INTR_KERNEL_CMD,
FG_KERNEL_CMD_UPDATE_AVG_BATTEMP,
param);
bm_err(
"exe_BAT_EC cmd %d,update mavg temp\n",
cmd);
}
break;
case 794:
{
wakeup_fg_algo_cmd(gm,
FG_INTR_KERNEL_CMD,
FG_KERNEL_CMD_SAVE_DEBUG_PARAM,
param);
bm_err(
"exe_BAT_EC cmd %d,FG_KERNEL_CMD_SAVE_DEBUG_PARAM\n",
cmd);
}
break;
case 795:
{
/*TODO*/
bm_err(
"exe_BAT_EC cmd %d,change aging to=%d\n",
cmd, param);
}
break;
case 796:
{
/*TODO*/
bm_err(
"exe_BAT_EC cmd %d,FG_KERNEL_CMD_AG_LOG_TEST=%d\n",
cmd, param);
}
break;
case 797:
{
bm_err(
"exe_BAT_EC cmd %d,GAUGE_PROP_CAR_TUNE_VALUE, current=%d\n",
cmd, param);
gauge_set_property(GAUGE_PROP_CAR_TUNE_VALUE,
param);
}
break;
case 798:
{
bm_err(
"exe_BAT_EC cmd %d,FG_KERNEL_CMD_CHG_DECIMAL_RATE=%d\n",
cmd, param);
}
break;
case 799:
{
bm_err(
"exe_BAT_EC cmd %d, FG_DAEMON_CMD_GET_IS_FORCE_FULL, force_full =%d\n",
cmd, param);
gm->is_force_full = param;
wakeup_fg_algo(gm, FG_INTR_CHR_FULL);
}
break;
default:
bm_err(
"exe_BAT_EC cmd %d, param %d, default\n",
cmd, param);
break;
}
}
/*=========================*/
/* adb */
/*=========================*/
static ssize_t Battery_Temperature_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("%s, %d %d\n", __func__, gm->bs_data.bat_batt_temp,
gm->fixed_bat_tmp);
return sprintf(buf, "%d\n", gm->fixed_bat_tmp);
}
static ssize_t Battery_Temperature_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
signed int temp;
int curr_bat_temp;
struct mtk_battery *gm;
gm = get_mtk_battery();
if (kstrtoint(buf, 10, &temp) == 0) {
gm->fixed_bat_tmp = temp;
if (gm->fixed_bat_tmp == 0xffff)
fg_bat_temp_int_internal(gm);
else {
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_LT, 0);
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_HT, 0);
wakeup_fg_algo(gm, FG_INTR_BAT_TMP_C_HT);
wakeup_fg_algo(gm, FG_INTR_BAT_TMP_HT);
}
curr_bat_temp = force_get_tbat(gm, true);
bm_err(
"%s: fixed_bat_tmp:%d ,tmp:%d!\n",
__func__,
temp, curr_bat_temp);
gm->bs_data.bat_batt_temp = curr_bat_temp;
battery_update(gm);
} else {
bm_err("%s: format error!\n", __func__);
}
return size;
}
static ssize_t UI_SOC_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("%s: %d %d\n",
__func__,
gm->ui_soc, gm->fixed_uisoc);
return sprintf(buf, "%d\n", gm->fixed_uisoc);
}
static ssize_t UI_SOC_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
struct mtk_battery *gm;
signed int temp;
gm = get_mtk_battery();
if (kstrtoint(buf, 10, &temp) == 0) {
gm->fixed_uisoc = temp;
bm_err("%s: %d %d\n",
__func__,
gm->ui_soc, gm->fixed_uisoc);
battery_update(gm);
}
return size;
}
static ssize_t uisoc_update_type_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_trace("[FG]%s:%d\n", __func__,
gm->fg_cust_data.uisoc_update_type);
return sprintf(buf, "%d\n", gm->fg_cust_data.uisoc_update_type);
}
static ssize_t uisoc_update_type_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val = 0;
int ret;
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("[%s]\n", __func__);
if (buf != NULL && size != 0) {
bm_err("[%s] buf is %s\n",
__func__, buf);
ret = kstrtoul(buf, 10, &val);
if (val < 0) {
bm_err(
"[%s] val is %d ??\n",
__func__,
(int)val);
val = 0;
}
if (val >= 0 && val <= 2) {
gm->fg_cust_data.uisoc_update_type = val;
wakeup_fg_algo_cmd(
gm,
FG_INTR_KERNEL_CMD,
FG_KERNEL_CMD_UISOC_UPDATE_TYPE,
val);
bm_err(
"[%s] type = %d\n",
__func__,
(int)val);
} else
bm_err(
"[%s] invalid type:%d\n",
__func__,
(int)val);
}
return size;
}
static ssize_t disable_nafg_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_trace("%s,[FG] show nafg disable : %d\n", __func__,
gm->cmd_disable_nafg);
return sprintf(buf, "%d\n", gm->cmd_disable_nafg);
}
static ssize_t disable_nafg_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val = 0;
int ret;
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("[%s]\n", __func__);
if (buf != NULL && size != 0) {
bm_err("[%s] buf is %s\n",
__func__, buf);
ret = kstrtoul(buf, 10, &val);
if (val < 0) {
bm_err(
"[%s] val is %d ??\n",
__func__,
(int)val);
val = 0;
}
if (val == 0)
gm->cmd_disable_nafg = false;
else
gm->cmd_disable_nafg = true;
wakeup_fg_algo_cmd(
gm, FG_INTR_KERNEL_CMD,
FG_KERNEL_CMD_DISABLE_NAFG, val);
bm_err(
"[%s] FG_nafg_disable = %d\n",
__func__,
(int)val);
}
return size;
}
static ssize_t ntc_disable_nafg_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_trace("[FG]%s: %d\n", __func__, gm->ntc_disable_nafg);
return sprintf(buf, "%d\n", gm->ntc_disable_nafg);
}
static ssize_t ntc_disable_nafg_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val = 0;
int ret;
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("[%s]\n", __func__);
if (buf != NULL && size != 0) {
bm_err("[%s] buf is %s\n", __func__, buf);
ret = kstrtoul(buf, 10, &val);
if (val < 0) {
bm_err(
"[%s] val is %d ??\n", __func__,
(int)val);
val = 0;
}
if (val == 0) {
gm->ntc_disable_nafg = false;
gm->Bat_EC_ctrl.fixed_temp_en = 0;
gm->Bat_EC_ctrl.fixed_temp_value = 25;
} else if (val == 1) {
gm->Bat_EC_ctrl.fixed_temp_en = 1;
gm->Bat_EC_ctrl.fixed_temp_value =
gm->fg_cust_data.battery_tmp_to_disable_nafg;
gm->ntc_disable_nafg = true;
wakeup_fg_algo(gm, FG_INTR_NAG_C_DLTV);
}
bm_err(
"[%s]val=%d, temp:%d %d, %d, BATTERY_TMP_TO_DISABLE_NAFG:%d\n",
__func__,
(int)val,
gm->Bat_EC_ctrl.fixed_temp_en,
gm->Bat_EC_ctrl.fixed_temp_value,
gm->ntc_disable_nafg,
gm->fg_cust_data.battery_tmp_to_disable_nafg);
}
return size;
}
static ssize_t FG_meter_resistance_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_trace("[FG] show com_fg_meter_resistance : %d\n",
gm->fg_cust_data.com_fg_meter_resistance);
return sprintf(buf, "%d\n", gm->fg_cust_data.com_fg_meter_resistance);
}
static ssize_t FG_meter_resistance_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val = 0;
int ret;
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("[%s]\n", __func__);
if (buf != NULL && size != 0) {
bm_err("[%s] buf is %s\n",
__func__, buf);
ret = kstrtoul(buf, 10, &val);
if (val < 0) {
bm_err(
"[%s] val is %d ??\n",
__func__,
(int)val);
val = 0;
} else
gm->fg_cust_data.com_fg_meter_resistance = val;
bm_err(
"[%s] com FG_meter_resistance = %d\n",
__func__,
(int)val);
}
return size;
}
static ssize_t FG_daemon_log_level_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
static int loglevel_count;
gm = get_mtk_battery();
loglevel_count++;
if (loglevel_count % 5 == 0)
bm_err(
"[FG] show FG_daemon_log_level : %d\n",
gm->fg_cust_data.daemon_log_level);
return sprintf(buf, "%d\n", gm->fg_cust_data.daemon_log_level);
}
static ssize_t FG_daemon_log_level_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val = 0;
int ret;
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("[FG_daemon_log_level]\n");
if (buf != NULL && size != 0) {
bm_err("[FG_daemon_log_level] buf is %s\n", buf);
ret = kstrtoul(buf, 10, &val);
if (val < 0) {
bm_err(
"[FG_daemon_log_level] val is %d ??\n",
(int)val);
val = 0;
}
if (val < 10 && val >= 0) {
gm->fg_cust_data.daemon_log_level = val;
wakeup_fg_algo_cmd(
gm,
FG_INTR_KERNEL_CMD,
FG_KERNEL_CMD_CHANG_LOGLEVEL,
val
);
}
bm_err(
"[FG_daemon_log_level]fg_cust_data.daemon_log_level=%d\n",
gm->fg_cust_data.daemon_log_level);
}
return size;
}
static ssize_t FG_daemon_disable_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_trace("%s[FG] show FG disable : %d\n", __func__, gm->disableGM30);
return sprintf(buf, "%d\n", gm->disableGM30);
}
static ssize_t FG_daemon_disable_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("[disable FG daemon]\n");
disable_fg(gm);
if (gm->disableGM30 == true)
gm->bs_data.bat_capacity = 50;
battery_update(gm);
return size;
}
static ssize_t FG_Battery_CurrentConsumption_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int ret_value = 8888;
ret_value = gauge_get_int_property(GAUGE_PROP_BATTERY_CURRENT) * 100;
bm_err("%s[EM] FG_Battery_CurrentConsumption : %d .1mA\n", __func__,
ret_value);
return sprintf(buf, "%d\n", ret_value);
}
static ssize_t FG_Battery_CurrentConsumption_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
bm_err("%s[EM] Not Support Write Function\n", __func__);
return size;
}
static ssize_t Power_On_Voltage_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int ret_value = 1;
ret_value = 3450;
bm_err("[EM] Power_On_Voltage : %d\n", ret_value);
return sprintf(buf, "%u\n", ret_value);
}
static ssize_t Power_On_Voltage_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
bm_err("%s[EM] Not Support Write Function\n", __func__);
return size;
}
static ssize_t Power_Off_Voltage_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int ret_value = 1;
ret_value = 3400;
bm_err("[EM] Power_Off_Voltage : %d\n", ret_value);
return sprintf(buf, "%u\n", ret_value);
}
static ssize_t Power_Off_Voltage_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
bm_err("%s[EM] Not Support Write Function\n", __func__);
return size;
}
static ssize_t shutdown_condition_enable_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
bm_err("%s\n", __func__);
gm = get_mtk_battery();
bm_trace(
"[FG] %s : %d\n",
__func__,
get_shutdown_cond_flag(gm));
return sprintf(buf, "%d\n", get_shutdown_cond_flag(gm));
}
static ssize_t shutdown_condition_enable_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val = 0;
int ret = 0;
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("[%s]\n", __func__);
if (buf != NULL && size != 0) {
bm_err("[%s] buf is %s\n",
__func__, buf);
ret = kstrtoul(buf, 10, &val);
if (val < 0) {
bm_err(
"[%s] val is %d ??\n",
__func__,
(int)val);
val = 0;
}
set_shutdown_cond_flag(gm, val);
bm_err(
"[%s] shutdown_cond_enabled=%d\n",
__func__,
get_shutdown_cond_flag(gm));
}
return size;
}
static ssize_t reset_battery_cycle_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_trace("[FG] %s : %d\n",
__func__,
gm->is_reset_battery_cycle);
return sprintf(buf, "%d\n", gm->is_reset_battery_cycle);
}
static ssize_t reset_battery_cycle_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val = 0;
int ret;
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("[%s]\n", __func__);
if (buf != NULL && size != 0) {
bm_err("[%s] buf is %s\n",
__func__, buf);
ret = kstrtoul(buf, 10, &val);
if (val < 0) {
bm_err(
"[%s] val is %d ??\n",
__func__,
(int)val);
val = 0;
}
if (val == 0)
gm->is_reset_battery_cycle = false;
else {
gm->is_reset_battery_cycle = true;
wakeup_fg_algo(gm, FG_INTR_BAT_CYCLE);
}
bm_err(
"%s=%d\n",
__func__,
gm->is_reset_battery_cycle);
}
return size;
}
static ssize_t reset_aging_factor_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_trace("[FG] %s : %d\n",
__func__,
gm->is_reset_aging_factor);
return sprintf(buf, "%d\n", gm->is_reset_aging_factor);
}
static ssize_t reset_aging_factor_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
unsigned long val = 0;
int ret;
struct mtk_battery *gm;
gm = get_mtk_battery();
bm_err("[%s]\n", __func__);
if (buf != NULL && size != 0) {
bm_err("[%s] buf is %s\n",
__func__, buf);
ret = kstrtoul(buf, 10, &val);
if (val < 0) {
bm_err(
"[%s] val is %d ??\n",
__func__,
(int)val);
val = 0;
}
if (val == 0)
gm->is_reset_aging_factor = false;
else {
gm->is_reset_aging_factor = true;
wakeup_fg_algo_cmd(gm, FG_INTR_KERNEL_CMD,
FG_KERNEL_CMD_RESET_AGING_FACTOR, 0);
}
bm_err(
"%s=%d\n",
__func__,
gm->is_reset_aging_factor);
}
return size;
}
static ssize_t BAT_EC_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
struct mtk_battery *gm;
bm_err("%s\n", __func__);
gm = get_mtk_battery();
return sprintf(buf, "%d:%d\n", gm->BAT_EC_cmd, gm->BAT_EC_param);
}
static ssize_t BAT_EC_store(
struct device *dev, struct device_attribute *attr,
const char *buf, size_t size)
{
int ret1 = 0, ret2 = 0;
char cmd_buf[4], param_buf[16];
struct mtk_battery *gm;
bm_err("%s\n", __func__);
gm = get_mtk_battery();
cmd_buf[3] = '\0';
param_buf[15] = '\0';
if (size < 4 || size > 20) {
bm_err("%s error, size mismatch\n",
__func__);
return -1;
}
if (buf != NULL && size != 0) {
bm_err("buf is %s\n", buf);
cmd_buf[0] = buf[0];
cmd_buf[1] = buf[1];
cmd_buf[2] = buf[2];
cmd_buf[3] = '\0';
if ((size - 4) > 0) {
strncpy(param_buf, buf + 4, size - 4);
param_buf[size - 4 - 1] = '\0';
bm_err("[FG_IT]cmd_buf %s, param_buf %s\n",
cmd_buf, param_buf);
ret2 = kstrtouint(param_buf, 10, &gm->BAT_EC_param);
}
ret1 = kstrtouint(cmd_buf, 10, &gm->BAT_EC_cmd);
if (ret1 != 0 || ret2 != 0) {
bm_err("ERROR! not valid number! %d %d\n",
ret1, ret2);
return -1;
}
bm_err("CMD is:%d, param:%d\n",
gm->BAT_EC_cmd, gm->BAT_EC_param);
}
exec_BAT_EC(gm->BAT_EC_cmd, gm->BAT_EC_param);
return size;
}
static DEVICE_ATTR_RW(Battery_Temperature);
static DEVICE_ATTR_RW(UI_SOC);
static DEVICE_ATTR_RW(uisoc_update_type);
static DEVICE_ATTR_RW(disable_nafg);
static DEVICE_ATTR_RW(ntc_disable_nafg);
static DEVICE_ATTR_RW(FG_meter_resistance);
static DEVICE_ATTR_RW(FG_daemon_log_level);
static DEVICE_ATTR_RW(FG_daemon_disable);
static DEVICE_ATTR_RW(FG_Battery_CurrentConsumption);
static DEVICE_ATTR_RW(Power_On_Voltage);
static DEVICE_ATTR_RW(Power_Off_Voltage);
static DEVICE_ATTR_RW(shutdown_condition_enable);
static DEVICE_ATTR_RW(reset_battery_cycle);
static DEVICE_ATTR_RW(reset_aging_factor);
static DEVICE_ATTR_RW(BAT_EC);
static int mtk_battery_setup_files(struct platform_device *pdev)
{
int ret = 0;
ret = device_create_file(&(pdev->dev), &dev_attr_Battery_Temperature);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_UI_SOC);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_uisoc_update_type);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_disable_nafg);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_ntc_disable_nafg);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_FG_meter_resistance);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_FG_daemon_log_level);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_FG_daemon_disable);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_BAT_EC);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev),
&dev_attr_FG_Battery_CurrentConsumption);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_Power_On_Voltage);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_Power_Off_Voltage);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev),
&dev_attr_shutdown_condition_enable);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_reset_battery_cycle);
if (ret)
goto _out;
ret = device_create_file(&(pdev->dev), &dev_attr_reset_aging_factor);
if (ret)
goto _out;
_out:
return ret;
}
static void mtk_battery_daemon_handler(struct mtk_battery *gm, void *nl_data,
struct fgd_nl_msg_t *ret_msg)
{
struct fgd_nl_msg_t *msg;
static int ptim_vbat, ptim_i;
int int_value;
static int badcmd;
if (gm == NULL)
gm = get_mtk_battery();
msg = nl_data;
ret_msg->nl_cmd = msg->nl_cmd;
ret_msg->fgd_cmd = msg->fgd_cmd;
switch (msg->fgd_cmd) {
case FG_DAEMON_CMD_IS_BAT_EXIST:
{
int is_bat_exist = 0;
gauge_get_property(GAUGE_PROP_BATTERY_EXIST, &is_bat_exist);
ret_msg->fgd_data_len += sizeof(is_bat_exist);
memcpy(ret_msg->fgd_data,
&is_bat_exist, sizeof(is_bat_exist));
bm_debug(
"[K]FG_DAEMON_CMD_IS_BAT_EXIST=%d\n",
is_bat_exist);
}
break;
case FG_DAEMON_CMD_FGADC_RESET:
{
bm_debug("[K]FG_DAEMON_CMD_FGADC_RESET\n");
battery_set_property(BAT_PROP_FG_RESET, 0);
}
break;
case FG_DAEMON_CMD_GET_INIT_FLAG:
{
ret_msg->fgd_data_len += sizeof(gm->init_flag);
memcpy(ret_msg->fgd_data,
&gm->init_flag, sizeof(gm->init_flag));
bm_debug(
"[K]FG_DAEMON_CMD_GET_INIT_FLAG=%d\n",
gm->init_flag);
}
break;
case FG_DAEMON_CMD_SET_INIT_FLAG:
{
memcpy(&gm->init_flag,
&msg->fgd_data[0], sizeof(gm->init_flag));
if (gm->init_flag == 1)
gauge_set_property(GAUGE_PROP_SHUTDOWN_CAR, -99999);
bm_debug(
"[K]FG_DAEMON_CMD_SET_INIT_FLAG=%d\n",
gm->init_flag);
}
break;
case FG_DAEMON_CMD_GET_TEMPERTURE: /* fix me */
{
bool update;
int temperture = 0;
memcpy(&update, &msg->fgd_data[0], sizeof(update));
temperture = force_get_tbat(gm, true);
bm_debug("[K]FG_DAEMON_CMD_GET_TEMPERTURE update=%d tmp:%d\n",
update, temperture);
ret_msg->fgd_data_len += sizeof(temperture);
memcpy(ret_msg->fgd_data,
&temperture, sizeof(temperture));
/* gFG_temp = temperture; */
}
break;
case FG_DAEMON_CMD_GET_RAC:
{
int rac;
rac = gauge_get_int_property(
GAUGE_PROP_PTIM_RESIST);
ret_msg->fgd_data_len += sizeof(rac);
memcpy(ret_msg->fgd_data, &rac, sizeof(rac));
bm_debug("[K]FG_DAEMON_CMD_GET_RAC=%d\n", rac);
}
break;
case FG_DAEMON_CMD_GET_DISABLE_NAFG:
{
int ret = 0;
if (gm->ntc_disable_nafg == true)
ret = 1;
else
ret = 0;
ret_msg->fgd_data_len += sizeof(ret);
memcpy(ret_msg->fgd_data, &ret, sizeof(ret));
bm_debug(
"[K]FG_DAEMON_CMD_GET_DISABLE_NAFG=%d\n",
ret);
}
break;
case FG_DAEMON_CMD_GET_PTIM_VBAT:
{
unsigned int ptim_bat_vol = 0;
signed int ptim_R_curr = 0;
struct power_supply *psy;
union power_supply_propval val;
psy = gm->gauge->psy;
if (gm->init_flag == 1) {
ptim_bat_vol = gauge_get_int_property(
GAUGE_PROP_PTIM_BATTERY_VOLTAGE) * 10;
power_supply_get_property(psy,
POWER_SUPPLY_PROP_CURRENT_NOW, &val);
bm_debug("[K]PTIM V %d I %d\n",
ptim_bat_vol, ptim_R_curr);
} else {
ptim_bat_vol = gm->ptim_lk_v;
ptim_R_curr = gm->ptim_lk_i;
if (ptim_bat_vol == 0) {
ptim_bat_vol = gauge_get_int_property(
GAUGE_PROP_PTIM_BATTERY_VOLTAGE) * 10;
power_supply_get_property(psy,
POWER_SUPPLY_PROP_CURRENT_NOW, &val);
}
bm_debug("[K]PTIM_LK V %d:%d I %d:%d\n",
gm->ptim_lk_v, ptim_bat_vol,
gm->ptim_lk_i, ptim_R_curr);
}
ptim_vbat = ptim_bat_vol;
ptim_i = ptim_R_curr;
ret_msg->fgd_data_len += sizeof(ptim_vbat);
memcpy(ret_msg->fgd_data,
&ptim_vbat, sizeof(ptim_vbat));
}
break;
case FG_DAEMON_CMD_GET_PTIM_I:
{
ret_msg->fgd_data_len += sizeof(ptim_i);
memcpy(ret_msg->fgd_data, &ptim_i, sizeof(ptim_i));
bm_debug(
"[K]FG_DAEMON_CMD_GET_PTIM_I=%d\n", ptim_i);
}
break;
case FG_DAEMON_CMD_IS_CHARGER_EXIST:
{
/* todo */
int is_charger_exist = 0;
if (gm->bs_data.bat_status == POWER_SUPPLY_STATUS_CHARGING)
is_charger_exist = true;
else
is_charger_exist = false;
ret_msg->fgd_data_len += sizeof(is_charger_exist);
memcpy(ret_msg->fgd_data,
&is_charger_exist, sizeof(is_charger_exist));
bm_debug(
"[K]FG_DAEMON_CMD_IS_CHARGER_EXIST=%d\n",
is_charger_exist);
}
break;
case FG_DAEMON_CMD_GET_HW_OCV:
{
int voltage = 0;
gm->bs_data.bat_batt_temp = force_get_tbat(gm, true);
voltage = gauge_get_int_property(
GAUGE_PROP_BOOT_ZCV);
gm->gauge->hw_status.hw_ocv = voltage;
ret_msg->fgd_data_len += sizeof(voltage);
memcpy(ret_msg->fgd_data, &voltage, sizeof(voltage));
bm_debug("[K]FG_DAEMON_CMD_GET_HW_OCV=%d\n", voltage);
#ifdef GM_SIMULATOR
gm->log.phone_state = 1;
gm->log.ps_logtime = fg_get_log_sec();
gm->log.ps_system_time = fg_get_system_sec();
gm3_log_dump(true);
#endif
}
break;
case FG_DAEMON_CMD_GET_FG_SW_CAR_NAFG_CNT:
{
int cnt = 0;
int update;
memcpy(&update, &msg->fgd_data[0], sizeof(update));
if (update == 1)
cnt = gauge_get_int_property(GAUGE_PROP_NAFG_CNT);
else
cnt = gm->gauge->hw_status.nafg_cnt;
ret_msg->fgd_data_len += sizeof(cnt);
memcpy(ret_msg->fgd_data, &cnt, sizeof(cnt));
bm_debug(
"[K]BATTERY_METER_CMD_GET_SW_CAR_NAFG_CNT=%d\n",
cnt);
}
break;
case FG_DAEMON_CMD_GET_FG_SW_CAR_NAFG_DLTV:
{
int dltv = 0;
int update;
memcpy(&update, &msg->fgd_data[0], sizeof(update));
if (update == 1)
dltv = gauge_get_int_property(GAUGE_PROP_NAFG_DLTV);
else
dltv = gm->gauge->hw_status.nafg_dltv;
ret_msg->fgd_data_len += sizeof(dltv);
memcpy(ret_msg->fgd_data, &dltv, sizeof(dltv));
bm_debug(
"[K]BATTERY_METER_CMD_GET_SW_CAR_NAFG_DLTV=%d\n",
dltv);
}
break;
case FG_DAEMON_CMD_GET_FG_SW_CAR_NAFG_C_DLTV:
{
int c_dltv = 0;
int update;
memcpy(&update, &msg->fgd_data[0], sizeof(update));
if (update == 1)
c_dltv = gauge_get_int_property(GAUGE_PROP_NAFG_C_DLTV);
else
c_dltv = gm->gauge->hw_status.nafg_c_dltv;
ret_msg->fgd_data_len += sizeof(c_dltv);
memcpy(ret_msg->fgd_data, &c_dltv, sizeof(c_dltv));
bm_debug(
"[K]BATTERY_METER_CMD_GET_SW_CAR_NAFG_C_DLTV=%d\n",
c_dltv);
}
break;
case FG_DAEMON_CMD_GET_FG_HW_CAR:
{
int fg_coulomb = 0;
fg_coulomb = gauge_get_int_property(GAUGE_PROP_COULOMB);
ret_msg->fgd_data_len += sizeof(fg_coulomb);
memcpy(ret_msg->fgd_data,
&fg_coulomb, sizeof(fg_coulomb));
bm_debug(
"[K]BATTERY_METER_CMD_GET_FG_HW_CAR=%d\n",
fg_coulomb);
}
break;
case FG_DAEMON_CMD_SET_SW_OCV:
{
int _sw_ocv;
memcpy(&_sw_ocv, &msg->fgd_data[0], sizeof(_sw_ocv));
gm->gauge->hw_status.sw_ocv = _sw_ocv;
bm_debug("[K]FG_DAEMON_CMD_SET_SW_OCV=%d\n", _sw_ocv);
}
break;
case FG_DAEMON_CMD_SET_FG_TIME:
{
int secs;
struct timespec time, time_now, end_time;
ktime_t ktime;
memcpy(&secs, &msg->fgd_data[0], sizeof(secs));
if (secs != 0 && secs > 0) {
get_monotonic_boottime(&time_now);
time.tv_sec = secs;
time.tv_nsec = 0;
end_time = timespec_add(time_now, time);
ktime = ktime_set(end_time.tv_sec, end_time.tv_nsec);
if (msg->fgd_subcmd_para1 == 0)
alarm_start(&gm->tracking_timer, ktime);
else
alarm_start(&gm->one_percent_timer, ktime);
} else {
if (msg->fgd_subcmd_para1 == 0)
alarm_cancel(&gm->tracking_timer);
else
alarm_cancel(&gm->one_percent_timer);
}
bm_debug("[K]FG_DAEMON_CMD_SET_FG_TIME=%d cmd:%d %d\n",
secs,
msg->fgd_subcmd, msg->fgd_subcmd_para1);
}
break;
case FG_DAEMON_CMD_GET_FG_TIME:
{
int now_time_secs;
now_time_secs = fg_get_system_sec();
ret_msg->fgd_data_len += sizeof(now_time_secs);
memcpy(ret_msg->fgd_data,
&now_time_secs, sizeof(now_time_secs));
bm_debug(
"[K]FG_DAEMON_CMD_GET_NOW_TIME=%d\n",
now_time_secs);
}
break;
case FG_DAEMON_CMD_SET_FG_BAT_INT1_GAP:
{
int fg_coulomb = 0;
fg_coulomb = gauge_get_int_property(GAUGE_PROP_COULOMB);
memcpy(&gm->coulomb_int_gap,
&msg->fgd_data[0], sizeof(gm->coulomb_int_gap));
gm->coulomb_int_ht = fg_coulomb + gm->coulomb_int_gap;
gm->coulomb_int_lt = fg_coulomb - gm->coulomb_int_gap;
gauge_coulomb_start(&gm->coulomb_plus, gm->coulomb_int_gap);
gauge_coulomb_start(&gm->coulomb_minus, -gm->coulomb_int_gap);
bm_debug(
"[K]FG_DAEMON_CMD_SET_FG_BAT_INT1_GAP=%d car:%d\n",
gm->coulomb_int_gap, fg_coulomb);
}
break;
case FG_DAEMON_CMD_SET_FG_BAT_INT2_HT_GAP:
{
memcpy(&gm->uisoc_int_ht_gap,
&msg->fgd_data[0], sizeof(gm->uisoc_int_ht_gap));
gauge_coulomb_start(&gm->uisoc_plus, gm->uisoc_int_ht_gap);
bm_debug(
"[K]FG_DAEMON_CMD_SET_FG_BAT_INT2_HT_GAP=%d\n",
gm->uisoc_int_ht_gap);
}
break;
case FG_DAEMON_CMD_SET_FG_BAT_INT2_LT_GAP:
{
memcpy(&gm->uisoc_int_lt_gap,
&msg->fgd_data[0], sizeof(gm->uisoc_int_lt_gap));
gauge_coulomb_start(&gm->uisoc_minus, -gm->uisoc_int_lt_gap);
bm_debug(
"[K]FG_DAEMON_CMD_SET_FG_BAT_INT2_LT_GAP=%d\n",
gm->uisoc_int_lt_gap);
}
break;
case FG_DAEMON_CMD_ENABLE_FG_BAT_INT2_HT:
{
int ver;
ktime_t ktime;
ver = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
memcpy(&gm->uisoc_int_ht_en,
&msg->fgd_data[0], sizeof(gm->uisoc_int_ht_en));
if (gm->uisoc_int_ht_en == 0) {
if (ver != GAUGE_NO_HW)
gauge_coulomb_stop(&gm->uisoc_plus);
else if (gm->soc != gm->ui_soc) {
ktime = ktime_set(60, 0);
alarm_start(&gm->sw_uisoc_timer, ktime);
}
}
bm_debug(
"[K]FG_DAEMON_CMD_ENABLE_FG_BAT_INT2_HT=%d\n",
gm->uisoc_int_ht_en);
}
break;
case FG_DAEMON_CMD_ENABLE_FG_BAT_INT2_LT:
{
memcpy(&gm->uisoc_int_lt_en,
&msg->fgd_data[0], sizeof(gm->uisoc_int_lt_en));
if (gm->uisoc_int_lt_en == 0)
gauge_coulomb_stop(&gm->uisoc_minus);
bm_debug(
"[K]FG_DAEMON_CMD_ENABLE_FG_BAT_INT2_LT=%d\n",
gm->uisoc_int_lt_en);
}
break;
case FG_DAEMON_CMD_SET_FG_BAT_TMP_C_GAP:
{
int tmp = force_get_tbat(gm, true);
memcpy(&gm->bat_tmp_c_int_gap,
&msg->fgd_data[0], sizeof(gm->bat_tmp_c_int_gap));
gm->bat_tmp_c_ht = tmp + gm->bat_tmp_c_int_gap;
gm->bat_tmp_c_lt = tmp - gm->bat_tmp_c_int_gap;
bm_debug(
"[K]FG_DAEMON_CMD_SET_FG_BAT_TMP_C_GAP=%d ht:%d lt:%d\n",
gm->bat_tmp_c_int_gap,
gm->bat_tmp_c_ht,
gm->bat_tmp_c_lt);
}
break;
case FG_DAEMON_CMD_SET_FG_BAT_TMP_GAP:
{
int tmp = force_get_tbat(gm, true);
memcpy(
&gm->bat_tmp_int_gap, &msg->fgd_data[0],
sizeof(gm->bat_tmp_int_gap));
gm->bat_tmp_ht = tmp + gm->bat_tmp_int_gap;
gm->bat_tmp_lt = tmp - gm->bat_tmp_int_gap;
bm_debug(
"[K]FG_DAEMON_CMD_SET_FG_BAT_TMP_GAP=%d ht:%d lt:%d\n",
gm->bat_tmp_int_gap,
gm->bat_tmp_ht, gm->bat_tmp_lt);
}
break;
case FG_DAEMON_CMD_IS_BAT_PLUGOUT:
{
int is_bat_plugout = 0;
is_bat_plugout = gm->gauge->hw_status.is_bat_plugout;
ret_msg->fgd_data_len += sizeof(is_bat_plugout);
memcpy(ret_msg->fgd_data,
&is_bat_plugout, sizeof(is_bat_plugout));
bm_debug(
"[K]BATTERY_METER_CMD_GET_BOOT_BATTERY_PLUG_STATUS=%d\n",
is_bat_plugout);
}
break;
case FG_DAEMON_CMD_GET_BAT_PLUG_OUT_TIME:
{
unsigned int time = 0;
time = gm->gauge->hw_status.bat_plug_out_time;
ret_msg->fgd_data_len += sizeof(time);
memcpy(ret_msg->fgd_data, &time, sizeof(time));
bm_debug(
"[K]FG_DAEMON_CMD_GET_BAT_PLUG_OUT_TIME=%d\n",
time);
}
break;
case FG_DAEMON_CMD_IS_BAT_CHARGING:
{
int is_bat_charging = 0;
int bat_current = 0;
/* BAT_DISCHARGING = 0 */
/* BAT_CHARGING = 1 */
bat_current = gauge_get_int_property(
GAUGE_PROP_BATTERY_CURRENT);
if (bat_current > 0)
is_bat_charging = 1;
else
is_bat_charging = 0;
ret_msg->fgd_data_len += sizeof(is_bat_charging);
memcpy(ret_msg->fgd_data,
&is_bat_charging, sizeof(is_bat_charging));
bm_debug(
"[K]FG_DAEMON_CMD_IS_BAT_CHARGING=%d\n",
is_bat_charging);
}
break;
case FG_DAEMON_CMD_GET_CHARGER_STATUS:
{
int charger_status = 0;
/* charger status need charger API */
/* CHR_ERR = -1 */
/* CHR_NORMAL = 0 */
if (gm->bs_data.bat_status ==
POWER_SUPPLY_STATUS_NOT_CHARGING)
charger_status = -1;
else
charger_status = 0;
ret_msg->fgd_data_len += sizeof(charger_status);
memcpy(ret_msg->fgd_data,
&charger_status, sizeof(charger_status));
bm_debug(
"[K]FG_DAEMON_CMD_GET_CHARGER_STATUS=%d\n",
charger_status);
}
break;
case FG_DAEMON_CMD_CHECK_FG_DAEMON_VERSION:
{
/* todo */
bm_debug(
"[K]FG_DAEMON_CMD_CHECK_FG_DAEMON_VERSION\n");
}
break;
case FG_DAEMON_CMD_GET_SHUTDOWN_DURATION_TIME:
{
signed int time = 0;
time = gm->pl_shutdown_time;
ret_msg->fgd_data_len += sizeof(time);
memcpy(ret_msg->fgd_data, &time, sizeof(time));
bm_debug(
"[K]FG_DAEMON_CMD_GET_SHUTDOWN_DURATION_TIME=%d\n",
time);
}
break;
case FG_DAEMON_CMD_SET_FG_RESET_RTC_STATUS:
{
int fg_reset_rtc;
memcpy(&fg_reset_rtc, &msg->fgd_data[0], sizeof(fg_reset_rtc));
gauge_set_property(GAUGE_PROP_RESET_FG_RTC, 0);
bm_debug(
"[K]BATTERY_METER_CMD_SET_FG_RESET_RTC_STATUS=%d\n",
fg_reset_rtc);
}
break;
case FG_DAEMON_CMD_SET_IS_FG_INITIALIZED:
{
int fg_reset;
memcpy(&fg_reset, &msg->fgd_data[0], sizeof(fg_reset));
gauge_set_property(GAUGE_PROP_GAUGE_INITIALIZED, fg_reset);
bm_debug(
"[K]BATTERY_METER_CMD_SET_FG_RESET_STATUS=%d\n",
fg_reset);
}
break;
case FG_DAEMON_CMD_GET_IS_FG_INITIALIZED:
{
int fg_reset;
fg_reset = gauge_get_int_property(GAUGE_PROP_GAUGE_INITIALIZED);
ret_msg->fgd_data_len += sizeof(fg_reset);
memcpy(ret_msg->fgd_data, &fg_reset, sizeof(fg_reset));
bm_debug(
"[K]BATTERY_METER_CMD_GET_FG_RESET_STATUS=%d\n",
fg_reset);
}
break;
case FG_DAEMON_CMD_IS_HWOCV_UNRELIABLE:
{
int is_hwocv_unreliable;
is_hwocv_unreliable =
gm->gauge->hw_status.flag_hw_ocv_unreliable;
ret_msg->fgd_data_len += sizeof(is_hwocv_unreliable);
memcpy(ret_msg->fgd_data,
&is_hwocv_unreliable, sizeof(is_hwocv_unreliable));
bm_debug(
"[K]FG_DAEMON_CMD_IS_HWOCV_UNRELIABLE=%d\n",
is_hwocv_unreliable);
}
break;
case FG_DAEMON_CMD_GET_FG_CURRENT_AVG:
{
int fg_current_iavg = gm->sw_iavg;
bool valid;
int ver;
ver = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
if (ver >= GAUGE_HW_V2000)
fg_current_iavg =
gauge_get_average_current(gm, &valid);
ret_msg->fgd_data_len += sizeof(fg_current_iavg);
memcpy(ret_msg->fgd_data,
&fg_current_iavg, sizeof(fg_current_iavg));
bm_debug(
"[K]FG_DAEMON_CMD_GET_FG_CURRENT_AVG=%d %d v:%d\n",
fg_current_iavg, gm->sw_iavg, ver);
}
break;
case FG_DAEMON_CMD_GET_FG_CURRENT_IAVG_VALID:
{
bool valid = false;
int iavg_valid = true;
int ver;
ver = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
if (ver >= GAUGE_HW_V2000) {
gauge_get_average_current(gm, &valid);
iavg_valid = valid;
}
ret_msg->fgd_data_len += sizeof(iavg_valid);
memcpy(ret_msg->fgd_data, &iavg_valid, sizeof(iavg_valid));
bm_debug(
"[K]FG_DAEMON_CMD_GET_FG_CURRENT_IAVG_VALID=%d\n",
iavg_valid);
}
break;
case FG_DAEMON_CMD_GET_ZCV:
{
int zcv = 0;
zcv = gauge_get_int_property(GAUGE_PROP_ZCV);
ret_msg->fgd_data_len += sizeof(zcv);
memcpy(ret_msg->fgd_data, &zcv, sizeof(zcv));
bm_debug("[K]FG_DAEMON_CMD_GET_ZCV=%d\n", zcv);
}
break;
case FG_DAEMON_CMD_SET_NAG_ZCV_EN:
{
int nafg_zcv_en;
memcpy(&nafg_zcv_en, &msg->fgd_data[0], sizeof(nafg_zcv_en));
gauge_set_nag_en(gm, nafg_zcv_en);
bm_debug(
"[K]FG_DAEMON_CMD_SET_NAG_ZCV_EN=%d\n",
nafg_zcv_en);
}
break;
case FG_DAEMON_CMD_SET_NAG_ZCV:
{
int nafg_zcv;
memcpy(&nafg_zcv, &msg->fgd_data[0], sizeof(nafg_zcv));
gauge_set_property(GAUGE_PROP_NAFG_ZCV, nafg_zcv);
gm->log.nafg_zcv = nafg_zcv;
gm->gauge->hw_status.nafg_zcv = nafg_zcv;
bm_debug("[K]BATTERY_METER_CMD_SET_NAG_ZCV=%d\n", nafg_zcv);
}
break;
case FG_DAEMON_CMD_SET_NAG_C_DLTV:
{
int nafg_c_dltv;
memcpy(&nafg_c_dltv, &msg->fgd_data[0], sizeof(nafg_c_dltv));
gm->gauge->hw_status.nafg_c_dltv_th = nafg_c_dltv;
gauge_set_property(GAUGE_PROP_NAFG_C_DLTV, nafg_c_dltv);
gauge_set_nag_en(gm, 1);
bm_debug(
"[K]BATTERY_METER_CMD_SET_NAG_C_DLTV=%d\n",
nafg_c_dltv);
}
break;
case FG_DAEMON_CMD_SET_IAVG_INTR:
{
bm_err("[K]FG_DAEMON_CMD_SET_IAVG_INTR is removed\n");
}
break;
case FG_DAEMON_CMD_SET_BAT_PLUGOUT_INTR:
{
int fg_bat_plugout_en;
memcpy(&fg_bat_plugout_en,
&msg->fgd_data[0], sizeof(fg_bat_plugout_en));
gauge_set_property(GAUGE_PROP_BAT_PLUGOUT_EN,
fg_bat_plugout_en);
bm_debug(
"[K]BATTERY_METER_CMD_SET_BAT_PLUGOUT_INTR_EN=%d\n",
fg_bat_plugout_en);
}
break;
case FG_DAEMON_CMD_SET_ZCV_INTR:
{
int fg_zcv_current;
memcpy(&fg_zcv_current,
&msg->fgd_data[0], sizeof(fg_zcv_current));
gauge_set_property(GAUGE_PROP_ZCV_INTR_THRESHOLD,
fg_zcv_current);
gauge_set_property(GAUGE_PROP_ZCV_INTR_EN, 1);
bm_debug(
"[K]BATTERY_METER_CMD_SET_ZCV_INTR=%d\n",
fg_zcv_current);
}
break;
case FG_DAEMON_CMD_SET_FG_QUSE:/* tbd */
{
int fg_quse;
memcpy(&fg_quse, &msg->fgd_data[0], sizeof(fg_quse));
bm_debug("[K]FG_DAEMON_CMD_SET_FG_QUSE=%d\n", fg_quse);
}
break;
case FG_DAEMON_CMD_SET_FG_DC_RATIO:/* tbd */
{
int fg_dc_ratio;
memcpy(&fg_dc_ratio, &msg->fgd_data[0], sizeof(fg_dc_ratio));
bm_debug(
"[K]BATTERY_METER_CMD_SET_FG_DC_RATIO=%d\n",
fg_dc_ratio);
}
break;
case FG_DAEMON_CMD_SOFF_RESET:
{
gauge_set_property(GAUGE_PROP_SOFF_RESET, 1);
bm_debug("[K]BATTERY_METER_CMD_SOFF_RESET\n");
}
break;
case FG_DAEMON_CMD_NCAR_RESET:
{
gauge_set_property(GAUGE_PROP_NCAR_RESET, 1);
bm_debug("[K]BATTERY_METER_CMD_NCAR_RESET\n");
}
break;
case FG_DAEMON_CMD_SET_BATTERY_CYCLE_THRESHOLD:
{
memcpy(&gm->bat_cycle_thr,
&msg->fgd_data[0], sizeof(gm->bat_cycle_thr));
gauge_set_property(GAUGE_PROP_BAT_CYCLE_INTR_THRESHOLD,
gm->bat_cycle_thr);
bm_debug(
"[K]FG_DAEMON_CMD_SET_BATTERY_CYCLE_THRESHOLD=%d\n",
gm->bat_cycle_thr);
fg_sw_bat_cycle_accu(gm);
}
break;
case FG_DAEMON_CMD_GET_IMIX:
{
int imix = UNIT_TRANS_10 * fg_get_imix();
ret_msg->fgd_data_len += sizeof(imix);
memcpy(ret_msg->fgd_data, &imix, sizeof(imix));
bm_debug("[K]FG_DAEMON_CMD_GET_IMIX=%d\n", imix);
}
break;
case FG_DAEMON_CMD_IS_BATTERY_CYCLE_RESET:
{
int reset = gm->is_reset_battery_cycle;
ret_msg->fgd_data_len += sizeof(reset);
memcpy(ret_msg->fgd_data, &reset, sizeof(reset));
bm_debug(
"[K]FG_DAEMON_CMD_IS_BATTERY_CYCLE_RESET = %d\n",
reset);
gm->is_reset_battery_cycle = false;
}
break;
case FG_DAEMON_CMD_GET_AGING_FACTOR_CUST:
{
int aging_factor_cust = 0;
int origin_aging_factor;
memcpy(&origin_aging_factor,
&msg->fgd_data[0], sizeof(origin_aging_factor));
aging_factor_cust =
get_customized_aging_factor(origin_aging_factor);
ret_msg->fgd_data_len += sizeof(aging_factor_cust);
memcpy(ret_msg->fgd_data,
&aging_factor_cust, sizeof(aging_factor_cust));
bm_debug(
"[K]FG_DAEMON_CMD_GET_AGING_FACTOR_CUST = %d\n",
aging_factor_cust);
}
break;
case FG_DAEMON_CMD_GET_D0_C_SOC_CUST:
{
int d0_c_cust = 0;
int origin_d0_c;
memcpy(&origin_d0_c, &msg->fgd_data[0], sizeof(origin_d0_c));
d0_c_cust = get_customized_d0_c_soc(origin_d0_c);
ret_msg->fgd_data_len += sizeof(d0_c_cust);
memcpy(ret_msg->fgd_data, &d0_c_cust, sizeof(d0_c_cust));
bm_debug(
"[K]FG_DAEMON_CMD_GET_D0_C_CUST = %d\n",
d0_c_cust);
}
break;
case FG_DAEMON_CMD_GET_D0_V_SOC_CUST:
{
int d0_v_cust = 0;
int origin_d0_v;
memcpy(&origin_d0_v, &msg->fgd_data[0], sizeof(origin_d0_v));
d0_v_cust = get_customized_d0_v_soc(origin_d0_v);
ret_msg->fgd_data_len += sizeof(d0_v_cust);
memcpy(ret_msg->fgd_data, &d0_v_cust, sizeof(d0_v_cust));
bm_debug(
"[K]FG_DAEMON_CMD_GET_D0_V_CUST = %d\n",
d0_v_cust);
}
break;
case FG_DAEMON_CMD_GET_UISOC_CUST:
{
int uisoc_cust = 0;
int origin_uisoc;
memcpy(&origin_uisoc, &msg->fgd_data[0], sizeof(origin_uisoc));
uisoc_cust = get_customized_uisoc(origin_uisoc);
ret_msg->fgd_data_len += sizeof(uisoc_cust);
memcpy(ret_msg->fgd_data, &uisoc_cust, sizeof(uisoc_cust));
bm_debug(
"[K]FG_DAEMON_CMD_GET_UISOC_CUST = %d\n",
uisoc_cust);
}
break;
case FG_DAEMON_CMD_IS_KPOC:
{
int is_kpoc = is_kernel_power_off_charging();
ret_msg->fgd_data_len += sizeof(is_kpoc);
memcpy(ret_msg->fgd_data, &is_kpoc, sizeof(is_kpoc));
bm_debug(
"[K]FG_DAEMON_CMD_IS_KPOC = %d\n", is_kpoc);
}
break;
case FG_DAEMON_CMD_GET_NAFG_VBAT:
{
int nafg_vbat;
nafg_vbat = gauge_get_int_property(GAUGE_PROP_NAFG_VBAT);
ret_msg->fgd_data_len += sizeof(nafg_vbat);
memcpy(ret_msg->fgd_data, &nafg_vbat, sizeof(nafg_vbat));
bm_debug(
"[K]FG_DAEMON_CMD_GET_NAFG_VBAT = %d\n",
nafg_vbat);
}
break;
case FG_DAEMON_CMD_GET_HW_INFO:
{
gauge_set_property(GAUGE_PROP_HW_INFO, 1);
bm_debug(
"[K]FG_DAEMON_CMD_GET_HW_INFO\n");
}
break;
case FG_DAEMON_CMD_SET_KERNEL_SOC:
{
int daemon_soc;
int soc_type;
soc_type = msg->fgd_subcmd_para1;
memcpy(&daemon_soc, &msg->fgd_data[0], sizeof(daemon_soc));
if (soc_type == 0)
gm->soc = (daemon_soc + 50) / 100;
bm_debug(
"[K]FG_DAEMON_CMD_SET_KERNEL_SOC = %d %d, type:%d\n",
daemon_soc, gm->soc, soc_type);
}
break;
case FG_DAEMON_CMD_SET_KERNEL_UISOC:
{
int daemon_ui_soc;
int old_uisoc;
struct timespec now_time, diff;
memcpy(&daemon_ui_soc, &msg->fgd_data[0],
sizeof(daemon_ui_soc));
if (daemon_ui_soc < 0) {
bm_debug("FG_DAEMON_CMD_SET_KERNEL_UISOC error,daemon_ui_soc:%d\n",
daemon_ui_soc);
daemon_ui_soc = 0;
}
gm->fg_cust_data.ui_old_soc = daemon_ui_soc;
old_uisoc = gm->ui_soc;
if (gm->disableGM30 == true)
gm->ui_soc = 50;
else
gm->ui_soc = (daemon_ui_soc + 50) / 100;
/* when UISOC changes, check the diff time for smooth */
if (old_uisoc != gm->ui_soc) {
get_monotonic_boottime(&now_time);
diff = timespec_sub(now_time, gm->uisoc_oldtime);
bm_err("[K]FG_DAEMON_CMD_SET_KERNEL_UISOC = %d %d GM3:%d old:%d diff=%ld\n",
daemon_ui_soc, gm->ui_soc,
gm->disableGM30, old_uisoc, diff.tv_sec);
gm->uisoc_oldtime = now_time;
gm->bs_data.bat_capacity = gm->ui_soc;
battery_update(gm);
} else {
bm_debug("[K]FG_DAEMON_CMD_SET_KERNEL_UISOC = %d %d GM3:%d\n",
daemon_ui_soc, gm->ui_soc, gm->disableGM30);
/* ac_update(&ac_main); */
gm->bs_data.bat_capacity = gm->ui_soc;
battery_update(gm);
}
}
break;
case FG_DAEMON_CMD_SET_KERNEL_INIT_VBAT:
{
int daemon_init_vbat;
memcpy(&daemon_init_vbat, &msg->fgd_data[0],
sizeof(daemon_init_vbat));
bm_debug(
"[K]FG_DAEMON_CMD_SET_KERNEL_INIT_VBAT = %d\n",
daemon_init_vbat);
}
break;
case FG_DAEMON_CMD_SET_FG_SHUTDOWN_COND:
{
int shutdown_cond;
memcpy(&shutdown_cond, &msg->fgd_data[0],
sizeof(shutdown_cond));
set_shutdown_cond(gm, shutdown_cond);
bm_debug(
"[K]FG_DAEMON_CMD_SET_FG_SHUTDOWN_COND = %d\n",
shutdown_cond);
}
break;
case FG_DAEMON_CMD_GET_FG_SHUTDOWN_COND:
{
unsigned int shutdown_cond = get_shutdown_cond(gm);
ret_msg->fgd_data_len += sizeof(shutdown_cond);
memcpy(ret_msg->fgd_data,
&shutdown_cond, sizeof(shutdown_cond));
bm_debug("[K] shutdown_cond = %d\n", shutdown_cond);
}
break;
case FG_DAEMON_CMD_ENABLE_FG_VBAT_L_INT:
{
int fg_vbat_l_en;
memcpy(&fg_vbat_l_en, &msg->fgd_data[0], sizeof(fg_vbat_l_en));
gauge_set_property(GAUGE_PROP_EN_LOW_VBAT_INTERRUPT,
fg_vbat_l_en);
bm_debug(
"[K]FG_DAEMON_CMD_ENABLE_FG_VBAT_L_INT = %d\n",
fg_vbat_l_en);
}
break;
case FG_DAEMON_CMD_ENABLE_FG_VBAT_H_INT:
{
int fg_vbat_h_en;
memcpy(&fg_vbat_h_en, &msg->fgd_data[0], sizeof(fg_vbat_h_en));
gauge_set_property(GAUGE_PROP_EN_HIGH_VBAT_INTERRUPT,
fg_vbat_h_en);
bm_debug(
"[K]FG_DAEMON_CMD_ENABLE_FG_VBAT_H_INT = %d\n",
fg_vbat_h_en);
}
break;
case FG_DAEMON_CMD_SET_FG_VBAT_L_TH:
{
int fg_vbat_l_thr;
memcpy(&fg_vbat_l_thr,
&msg->fgd_data[0], sizeof(fg_vbat_l_thr));
gauge_set_property(GAUGE_PROP_VBAT_LT_INTR_THRESHOLD,
fg_vbat_l_thr);
set_shutdown_vbat_lt(gm,
fg_vbat_l_thr, gm->fg_cust_data.vbat2_det_voltage1);
bm_debug(
"[K]FG_DAEMON_CMD_SET_FG_VBAT_L_TH = %d\n",
fg_vbat_l_thr);
}
break;
case FG_DAEMON_CMD_SET_FG_VBAT_H_TH:
{
int fg_vbat_h_thr;
memcpy(&fg_vbat_h_thr, &msg->fgd_data[0],
sizeof(fg_vbat_h_thr));
gauge_set_property(GAUGE_PROP_VBAT_HT_INTR_THRESHOLD,
fg_vbat_h_thr);
bm_debug(
"[K]FG_DAEMON_CMD_SET_FG_VBAT_H_TH=%d\n",
fg_vbat_h_thr);
}
break;
case FG_DAEMON_CMD_SET_CAR_TUNE_VALUE:
{
signed int cali_car_tune;
memcpy(
&cali_car_tune,
&msg->fgd_data[0],
sizeof(cali_car_tune));
#ifdef CALIBRATE_CAR_TUNE_VALUE_BY_META_TOOL
bm_err("[K] cali_car_tune = %d, default = %d, Use [cali_car_tune]\n",
cali_car_tune, gm->fg_cust_data.car_tune_value);
gm->fg_cust_data.car_tune_value = cali_car_tune;
#else
bm_err("[K] cali_car_tune = %d, default = %d, Use [default]\n",
cali_car_tune, gm->fg_cust_data.car_tune_value);
#endif
}
break;
case FG_DAEMON_CMD_GET_RTC_UI_SOC:
{
int rtc_ui_soc;
rtc_ui_soc = gauge_get_int_property(GAUGE_PROP_RTC_UI_SOC);
ret_msg->fgd_data_len += sizeof(rtc_ui_soc);
memcpy(ret_msg->fgd_data, &rtc_ui_soc,
sizeof(rtc_ui_soc));
bm_debug("[K]FG_DAEMON_CMD_GET_RTC_UI_SOC = %d\n",
rtc_ui_soc);
}
break;
case FG_DAEMON_CMD_SET_RTC_UI_SOC:
{
int rtc_ui_soc;
memcpy(&rtc_ui_soc, &msg->fgd_data[0], sizeof(rtc_ui_soc));
if (rtc_ui_soc < 0) {
bm_err("[K]FG_DAEMON_CMD_SET_RTC_UI_SOC error,rtc_ui_soc=%d\n",
rtc_ui_soc);
rtc_ui_soc = 0;
}
gauge_set_property(GAUGE_PROP_RTC_UI_SOC, rtc_ui_soc);
bm_debug(
"[K] BATTERY_METER_CMD_SET_RTC_UI_SOC=%d\n",
rtc_ui_soc);
}
break;
case FG_DAEMON_CMD_SET_CON0_SOC:
{
int _soc = 0;
memcpy(&_soc, &msg->fgd_data[0], sizeof(_soc));
gauge_set_property(GAUGE_PROP_CON0_SOC, _soc);
bm_debug("[K]FG_DAEMON_CMD_SET_CON0_SOC = %d\n", _soc);
}
break;
case FG_DAEMON_CMD_GET_CON0_SOC:
{
int _soc = 0;
_soc = gauge_get_int_property(GAUGE_PROP_CON0_SOC);
ret_msg->fgd_data_len += sizeof(_soc);
memcpy(ret_msg->fgd_data, &_soc, sizeof(_soc));
bm_debug("[K]FG_DAEMON_CMD_GET_CON0_SOC = %d\n", _soc);
}
break;
case FG_DAEMON_CMD_GET_NVRAM_FAIL_STATUS:
{
int flag = 0;
flag = gauge_get_int_property(GAUGE_PROP_IS_NVRAM_FAIL_MODE);
ret_msg->fgd_data_len += sizeof(flag);
memcpy(ret_msg->fgd_data, &flag, sizeof(flag));
bm_debug(
"[K]FG_DAEMON_CMD_GET_NVRAM_FAIL_STATUS = %d\n",
flag);
}
break;
case FG_DAEMON_CMD_SET_NVRAM_FAIL_STATUS:
{
int flag = 0;
memcpy(&flag, &msg->fgd_data[0], sizeof(flag));
gauge_set_property(GAUGE_PROP_IS_NVRAM_FAIL_MODE, flag);
bm_debug(
"[K]FG_DAEMON_CMD_SET_NVRAM_FAIL_STATUS = %d\n",
flag);
}
break;
case FG_DAEMON_CMD_GET_RTC_TWO_SEC_REBOOT:
{
int two_sec_reboot_flag;
two_sec_reboot_flag = gm->pl_two_sec_reboot;
ret_msg->fgd_data_len += sizeof(two_sec_reboot_flag);
memcpy(ret_msg->fgd_data,
&two_sec_reboot_flag,
sizeof(two_sec_reboot_flag));
bm_debug(
"[K]FG_DAEMON_CMD_GET_RTC_TWO_SEC_REBOOT = %d\n",
two_sec_reboot_flag);
}
break;
case FG_DAEMON_CMD_GET_RTC_INVALID:
{
int rtc_invalid;
rtc_invalid = gm->gauge->hw_status.rtc_invalid;
ret_msg->fgd_data_len += sizeof(rtc_invalid);
memcpy(ret_msg->fgd_data, &rtc_invalid, sizeof(rtc_invalid));
bm_debug(
"[K]FG_DAEMON_CMD_GET_RTC_INVALID = %d\n",
rtc_invalid);
}
break;
case FG_DAEMON_CMD_SET_DAEMON_PID:
{
fg_cmd_check(msg);
/* check is daemon killed case*/
if (gm->fgd_pid == 0) {
memcpy(&gm->fgd_pid, &msg->fgd_data[0],
sizeof(gm->fgd_pid));
bm_err("[K]FG_DAEMON_CMD_SET_DAEMON_PID = %d(first launch)\n",
gm->fgd_pid);
} else {
memcpy(&gm->fgd_pid, &msg->fgd_data[0],
sizeof(gm->fgd_pid));
bm_err("[K]FG_DAEMON_CMD_SET_DAEMON_PID=%d,kill daemon:%d init_flag:%d (re-launch)\n",
gm->fgd_pid,
gm->Bat_EC_ctrl.debug_kill_daemontest,
gm->init_flag);
if (gm->Bat_EC_ctrl.debug_kill_daemontest != 1 &&
gm->init_flag == 1)
gm->fg_cust_data.dod_init_sel = 14;
}
}
break;
case FG_DAEMON_CMD_GET_VBAT:
{
unsigned int vbat = 0;
vbat = gauge_get_int_property(GAUGE_PROP_BATTERY_VOLTAGE) * 10;
ret_msg->fgd_data_len += sizeof(vbat);
memcpy(ret_msg->fgd_data, &vbat, sizeof(vbat));
bm_debug("[K]FG_DAEMON_CMD_GET_VBAT = %d\n", vbat);
}
break;
case FG_DAEMON_CMD_PRINT_LOG:
{
fg_cmd_check(msg);
bm_err("%s", &msg->fgd_data[0]);
}
break;
case FG_DAEMON_CMD_SEND_CUSTOM_TABLE:
{
fg_daemon_send_data(gm, FG_DAEMON_CMD_SEND_CUSTOM_TABLE,
&msg->fgd_data[0],
&ret_msg->fgd_data[0]);
}
break;
case FG_DAEMON_CMD_GET_CUSTOM_SETTING:
case FG_DAEMON_CMD_GET_CUSTOM_TABLE:
{
fg_cmd_check(msg);
bm_debug("[K]FG_DAEMON_CMD_GET_DATA\n");
fg_daemon_get_data(msg->fgd_cmd, &msg->fgd_data[0],
&ret_msg->fgd_data[0]);
ret_msg->fgd_data_len =
sizeof(struct fgd_cmd_param_t_4);
}
break;
case FG_DAEMON_CMD_DUMP_LOG:
{
bm_debug("[K]FG_DAEMON_CMD_DUMP_LOG %d %d %d\n",
msg->fgd_subcmd, msg->fgd_subcmd_para1,
(int)strlen(&msg->fgd_data[0]));
}
break;
case FG_DAEMON_CMD_GET_SHUTDOWN_CAR:
{
int shutdown_car_diff = 0;
int tmp_cardiff = 0;
shutdown_car_diff = gauge_get_int_property(
GAUGE_PROP_SHUTDOWN_CAR);
if (abs(shutdown_car_diff) > 1000) {
tmp_cardiff = shutdown_car_diff;
shutdown_car_diff = 0;
}
ret_msg->fgd_data_len += sizeof(shutdown_car_diff);
memcpy(ret_msg->fgd_data, &shutdown_car_diff,
sizeof(shutdown_car_diff));
bm_debug(
"[K]FG_DAEMON_CMD_GET_SHUTDOWN_CAR = %d, tmp=%d\n",
shutdown_car_diff, tmp_cardiff);
}
break;
case FG_DAEMON_CMD_GET_NCAR:
{
int ver;
ver = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
if (ver >= GAUGE_HW_V1000 &&
ver < GAUGE_HW_V2000)
memcpy(ret_msg->fgd_data, &gm->bat_cycle_ncar,
sizeof(gm->bat_cycle_ncar));
else {
gauge_set_property(GAUGE_PROP_HW_INFO, 1);
memcpy(ret_msg->fgd_data, &gm->gauge->fg_hw_info.ncar,
sizeof(gm->gauge->fg_hw_info.ncar));
}
bm_debug("[K]FG_DAEMON_CMD_GET_NCAR version:%d ncar:%d %d\n",
ver, gm->bat_cycle_ncar, gm->gauge->fg_hw_info.ncar);
}
break;
case FG_DAEMON_CMD_GET_CURR_1:
{
gauge_set_property(GAUGE_PROP_HW_INFO, 1);
memcpy(ret_msg->fgd_data, &gm->gauge->fg_hw_info.current_1,
sizeof(gm->gauge->fg_hw_info.current_1));
bm_debug("[K]FG_DAEMON_CMD_GET_CURR_1 %d\n",
gm->gauge->fg_hw_info.current_1);
}
break;
case FG_DAEMON_CMD_GET_CURR_2:
{
gauge_set_property(GAUGE_PROP_HW_INFO, 1);
memcpy(ret_msg->fgd_data, &gm->gauge->fg_hw_info.current_2,
sizeof(gm->gauge->fg_hw_info.current_2));
bm_debug("[K]FG_DAEMON_CMD_GET_CURR_2 %d\n",
gm->gauge->fg_hw_info.current_2);
}
break;
case FG_DAEMON_CMD_GET_REFRESH:
{
gauge_set_property(GAUGE_PROP_HW_INFO, 1);
bm_debug("[K]FG_DAEMON_CMD_GET_REFRESH\n");
}
break;
case FG_DAEMON_CMD_GET_IS_AGING_RESET:
{
int reset = gm->is_reset_aging_factor;
memcpy(ret_msg->fgd_data, &reset,
sizeof(reset));
gm->is_reset_aging_factor = 0;
bm_debug("[K]FG_DAEMON_CMD_GET_IS_AGING_RESET %d %d\n",
reset, gm->is_reset_aging_factor);
}
break;
case FG_DAEMON_CMD_SET_SOC:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->soc = (int_value + 50) / 100;
bm_debug("[K]FG_DAEMON_CMD_SET_SOC %d\n",
gm->soc);
}
break;
case FG_DAEMON_CMD_SET_C_D0_SOC:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->fg_cust_data.c_old_d0 = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_C_D0_SOC %d\n",
gm->fg_cust_data.c_old_d0);
}
break;
case FG_DAEMON_CMD_SET_V_D0_SOC:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->fg_cust_data.v_old_d0 = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_V_D0_SOC %d\n",
gm->fg_cust_data.v_old_d0);
}
break;
case FG_DAEMON_CMD_SET_C_SOC:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->fg_cust_data.c_soc = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_C_SOC %d\n",
gm->fg_cust_data.c_soc);
}
break;
case FG_DAEMON_CMD_SET_V_SOC:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->fg_cust_data.v_soc = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_V_SOC %d\n",
gm->fg_cust_data.v_soc);
}
break;
case FG_DAEMON_CMD_SET_QMAX_T_AGING:
{
/* todo */
bm_debug("[K]FG_DAEMON_CMD_SET_QMAX_T_AGING\n");
}
break;
case FG_DAEMON_CMD_SET_SAVED_CAR:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->d_saved_car = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_SAVED_CAR %d\n",
gm->d_saved_car);
}
break;
case FG_DAEMON_CMD_SET_AGING_FACTOR:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->aging_factor = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_AGING_FACTOR %d\n",
gm->aging_factor);
}
break;
case FG_DAEMON_CMD_SET_QMAX:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->algo_qmax = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_QMAX %d\n",
gm->algo_qmax);
}
break;
case FG_DAEMON_CMD_SET_BAT_CYCLES:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->bat_cycle = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_BAT_CYCLES %d\n",
gm->bat_cycle);
}
break;
case FG_DAEMON_CMD_SET_NCAR:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->bat_cycle_ncar = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_NCAR %d\n",
gm->bat_cycle_ncar);
}
break;
case FG_DAEMON_CMD_SET_OCV_MAH:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->algo_ocv_to_mah = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_OCV_MAH %d\n",
gm->algo_ocv_to_mah);
}
break;
case FG_DAEMON_CMD_SET_OCV_VTEMP:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->algo_vtemp = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_OCV_VTEMP %d\n",
gm->algo_vtemp);
}
break;
case FG_DAEMON_CMD_SET_OCV_SOC:
{
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
gm->algo_ocv_to_soc = int_value;
bm_debug("[K]FG_DAEMON_CMD_SET_OCV_SOC %d\n",
gm->algo_ocv_to_soc);
}
break;
case FG_DAEMON_CMD_SET_CON0_SOFF_VALID:
{
int ori_value = 0;
memcpy(&int_value, &msg->fgd_data[0], sizeof(int_value));
ori_value = gauge_get_int_property(
GAUGE_PROP_MONITOR_SOFF_VALIDTIME);
gauge_set_property(GAUGE_PROP_MONITOR_SOFF_VALIDTIME,
int_value);
bm_debug("[K]FG_DAEMON_CMD_SET_CON0_SOFF_VALID ori:%d, new:%d\n",
ori_value, int_value);
}
break;
case FG_DAEMON_CMD_SET_AGING_INFO:
bm_debug("[K]FG_DAEMON_CMD_SET_AGING_INFO\n");
break;
case FG_DAEMON_CMD_GET_SOC_DECIMAL_RATE:
{
int decimal_rate = gm->soc_decimal_rate;
ret_msg->fgd_data_len += sizeof(decimal_rate);
memcpy(ret_msg->fgd_data, &decimal_rate,
sizeof(decimal_rate));
bm_debug("[K]FG_DAEMON_CMD_GET_SOC_DECIMAL_RATE %d",
decimal_rate);
}
break;
case FG_DAEMON_CMD_GET_DIFF_SOC_SET:
{
int soc_setting = 1;
ret_msg->fgd_data_len += sizeof(soc_setting);
memcpy(ret_msg->fgd_data, &soc_setting,
sizeof(soc_setting));
bm_debug("[K]FG_DAEMON_CMD_GET_DIFF_SOC_SET %d", soc_setting);
}
break;
case FG_DAEMON_CMD_SET_ZCV_INTR_EN:
bm_debug("[K]FG_DAEMON_CMD_SET_ZCV_INTR_EN");
break;
case FG_DAEMON_CMD_GET_IS_FORCE_FULL:
{
/* 1 = trust customer full condition */
/* 0 = using gauge ori full flow */
int force_full = gm->is_force_full;
ret_msg->fgd_data_len += sizeof(force_full);
memcpy(ret_msg->fgd_data, &force_full,
sizeof(force_full));
bm_debug("[K]FG_DAEMON_CMD_GET_IS_FORCE_FULL %d", force_full);
};
break;
default:
badcmd++;
bm_err("[%s]bad cmd:0x%x times:%d\n", __func__,
msg->fgd_cmd, badcmd);
break;
}
}
void mtk_battery_netlink_handler(struct sk_buff *skb)
{
u32 pid;
kuid_t uid;
int seq;
void *data;
struct nlmsghdr *nlh;
struct fgd_nl_msg_t *fgd_msg, *fgd_ret_msg;
int size = 0;
static struct mtk_battery *gm;
if (gm == NULL)
gm = get_mtk_battery();
nlh = (struct nlmsghdr *)skb->data;
pid = NETLINK_CREDS(skb)->pid;
uid = NETLINK_CREDS(skb)->uid;
seq = nlh->nlmsg_seq;
data = NLMSG_DATA(nlh);
fgd_msg = (struct fgd_nl_msg_t *)data;
bm_debug("rcv:%d %d %d %d %d %d\n",
fgd_msg->nl_cmd,
fgd_msg->fgd_cmd,
fgd_msg->fgd_subcmd,
fgd_msg->fgd_subcmd_para1,
fgd_msg->fgd_data_len,
fgd_msg->identity);
if (fgd_msg->identity != FGD_NL_MAGIC) {
bm_err("[%s]not correct MTKFG netlink packet!%d\n",
__func__, fgd_msg->identity);
return;
}
if (gm->fgd_pid != pid &&
fgd_msg->fgd_cmd > FG_DAEMON_CMD_SET_DAEMON_PID) {
bm_err("[%s]drop rev netlink pid:%d:%d cmd:%d:%d\n",
__func__,
pid,
gm->fgd_pid,
fgd_msg->fgd_cmd,
FG_DAEMON_CMD_SET_DAEMON_PID);
return;
}
size = fgd_msg->fgd_ret_data_len + FGD_NL_HDR_LEN;
if (size > (PAGE_SIZE << 1))
fgd_ret_msg = vmalloc(size);
else {
if (in_interrupt())
fgd_ret_msg = kmalloc(size, GFP_ATOMIC);
else
fgd_ret_msg = kmalloc(size, GFP_KERNEL);
}
if (fgd_ret_msg == NULL) {
if (size > PAGE_SIZE)
fgd_ret_msg = vmalloc(size);
if (fgd_ret_msg == NULL)
return;
}
if (!fgd_ret_msg)
return;
memset(fgd_ret_msg, 0, size);
mtk_battery_daemon_handler(gm, data, fgd_ret_msg);
mtk_battery_send_to_user(gm, seq, fgd_ret_msg);
kvfree(fgd_ret_msg);
}
unsigned int TempConverBattThermistor(struct mtk_battery *gm, int temp)
{
int RES1 = 0, RES2 = 0;
int TMP1 = 0, TMP2 = 0;
int i;
unsigned int TBatt_R_Value = 0xffff;
struct fuelgauge_temperature *ptable;
ptable = gm->tmp_table;
if (temp >= ptable[20].BatteryTemp) {
TBatt_R_Value = ptable[20].TemperatureR;
} else if (temp <= ptable[0].BatteryTemp) {
TBatt_R_Value = ptable[0].TemperatureR;
} else {
RES1 = ptable[0].TemperatureR;
TMP1 = ptable[0].BatteryTemp;
for (i = 0; i <= 20; i++) {
if (temp <= ptable[i].BatteryTemp) {
RES2 = ptable[i].TemperatureR;
TMP2 = ptable[i].BatteryTemp;
break;
}
{ /* hidden else */
RES1 = ptable[i].TemperatureR;
TMP1 = ptable[i].BatteryTemp;
}
}
TBatt_R_Value = interpolation(TMP1, RES1, TMP2, RES2, temp);
}
bm_trace(
"[%s] [%d] %d %d %d %d %d\n",
__func__,
TBatt_R_Value, TMP1,
RES1, TMP2, RES2, temp);
return TBatt_R_Value;
}
unsigned int TempToBattVolt(struct mtk_battery *gm, int temp, int update)
{
unsigned int R_NTC = TempConverBattThermistor(gm, temp);
long long Vin = 0;
long long V_IR_comp = 0;
/*int vbif28 = pmic_get_auxadc_value(AUXADC_LIST_VBIF);*/
int vbif28 = gm->rbat.rbat_pull_up_volt;
static int fg_current_temp;
static bool fg_current_state;
int fg_r_value = gm->fg_cust_data.com_r_fg_value;
int fg_meter_res_value = 0;
if (gm->no_bat_temp_compensate == 0)
fg_meter_res_value = gm->fg_cust_data.com_fg_meter_resistance;
else
fg_meter_res_value = 0;
#ifdef RBAT_PULL_UP_VOLT_BY_BIF
vbif28 = gauge_get_int_property(GAUGE_PROP_BIF_VOLTAGE);
#endif
Vin = (long long)R_NTC * vbif28 * 10; /* 0.1 mV */
#if defined(__LP64__) || defined(_LP64)
do_div(Vin, (R_NTC + gm->rbat.rbat_pull_up_r));
#else
Vin = div_s64(Vin, (R_NTC + gm->rbat.rbat_pull_up_r));
#endif
if (update == true) {
fg_current_temp = gauge_get_int_property(
GAUGE_PROP_BATTERY_CURRENT);
if (fg_current_temp <= 0)
fg_current_state = false;
else
fg_current_state = true;
}
if (fg_current_state == true) {
V_IR_comp = Vin;
V_IR_comp +=
((fg_current_temp *
(fg_meter_res_value + fg_r_value)) / 10000);
} else {
V_IR_comp = Vin;
V_IR_comp -=
((fg_current_temp *
(fg_meter_res_value + fg_r_value)) / 10000);
}
bm_trace("[%s] temp %d R_NTC %d V(%lld %lld) I %d CHG %d\n",
__func__,
temp, R_NTC, Vin, V_IR_comp, fg_current_temp, fg_current_state);
return (unsigned int) V_IR_comp;
}
void fg_bat_temp_int_internal(struct mtk_battery *gm)
{
int tmp = 0;
int fg_bat_new_ht, fg_bat_new_lt;
if (gm->disableGM30) {
gm->bs_data.bat_batt_temp = 25;
battery_update(gm);
return;
}
#if defined(CONFIG_MTK_DISABLE_GAUGE) || defined(FIXED_TBAT_25)
gm->bs_data.bat_batt_temp = 25;
battery_update(gm);
tmp = 1;
fg_bat_new_ht = 1;
fg_bat_new_lt = 1;
return;
#else
tmp = force_get_tbat(gm, true);
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_LT, 0);
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_HT, 0);
// if (get_ec()->fixed_temp_en == 1)
// tmp = get_ec()->fixed_temp_value;
if (tmp >= gm->bat_tmp_c_ht)
wakeup_fg_algo(gm, FG_INTR_BAT_TMP_C_HT);
else if (tmp <= gm->bat_tmp_c_lt)
wakeup_fg_algo(gm, FG_INTR_BAT_TMP_C_LT);
if (tmp >= gm->bat_tmp_ht)
wakeup_fg_algo(gm, FG_INTR_BAT_TMP_HT);
else if (tmp <= gm->bat_tmp_lt)
wakeup_fg_algo(gm, FG_INTR_BAT_TMP_LT);
fg_bat_new_ht = TempToBattVolt(gm, tmp + 1, 1);
fg_bat_new_lt = TempToBattVolt(gm, tmp - 1, 0);
if (gm->fixed_bat_tmp == 0xffff) {
gauge_set_property(GAUGE_PROP_BAT_TMP_LT_THRESHOLD,
fg_bat_new_lt);
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_LT, 1);
gauge_set_property(GAUGE_PROP_BAT_TMP_HT_THRESHOLD,
fg_bat_new_ht);
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_HT, 1);
}
bm_debug("[%s][FG_TEMP_INT] T[%d] V[%d %d] C[%d %d] h[%d %d]\n",
__func__,
tmp, gm->bat_tmp_ht,
gm->bat_tmp_lt, gm->bat_tmp_c_ht,
gm->bat_tmp_c_lt,
fg_bat_new_lt, fg_bat_new_ht);
gm->bs_data.bat_batt_temp = tmp;
battery_update(gm);
#endif
}
void fg_bat_temp_int_sw_check(struct mtk_battery *gm)
{
int tmp = force_get_tbat(gm, true);
if (gm->disableGM30)
return;
bm_debug(
"[%s] tmp %d lt %d ht %d\n",
__func__,
tmp, gm->bat_tmp_lt,
gm->bat_tmp_ht);
if (tmp >= gm->bat_tmp_ht)
fg_bat_temp_int_internal(gm);
else if (tmp <= gm->bat_tmp_lt)
fg_bat_temp_int_internal(gm);
}
void fg_int_event(struct mtk_battery *gm, enum gauge_event evt)
{
if (evt != EVT_INT_NAFG_CHECK)
fg_bat_temp_int_sw_check(gm);
gauge_set_property(GAUGE_PROP_EVENT, evt);
}
/* ============================================================ */
/* check bat plug out */
/* ============================================================ */
void sw_check_bat_plugout(struct mtk_battery *gm)
{
int is_bat_exist;
if (gm->disable_plug_int && gm->disableGM30 != true) {
is_bat_exist = gauge_get_int_property(GAUGE_PROP_BATTERY_EXIST);
/* fg_bat_plugout_int_handler(); */
if (is_bat_exist == 0) {
bm_err(
"[swcheck_bat_plugout]g_disable_plug_int=%d, is_bat_exist %d, is_fg_disable %d\n",
gm->disable_plug_int,
is_bat_exist,
gm->disableGM30);
gm->bs_data.bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
wakeup_fg_algo(gm, FG_INTR_BAT_PLUGOUT);
battery_update(gm);
kernel_power_off();
}
}
}
/* ============================================================ */
/* sw low battery interrupt handler */
/* ============================================================ */
void fg_update_sw_low_battery_check(unsigned int thd)
{
int vbat;
int thd1, thd2, thd3;
struct mtk_battery *gm;
struct fuel_gauge_custom_data *fg_cust_data;
int version = 0;
gm = get_mtk_battery();
fg_cust_data = &gm->fg_cust_data;
thd1 = fg_cust_data->vbat2_det_voltage1 / 10;
thd2 = fg_cust_data->vbat2_det_voltage2 / 10;
thd3 = fg_cust_data->vbat2_det_voltage3 / 10;
gauge_get_property(GAUGE_PROP_HW_VERSION, &version);
if (version >= GAUGE_HW_V2000)
return;
vbat = gauge_get_int_property(GAUGE_PROP_BATTERY_VOLTAGE) * 10;
bm_err("[%s]vbat:%d %d ht:%d %d lt:%d %d\n",
__func__,
thd, vbat,
gm->sw_low_battery_ht_en,
gm->sw_low_battery_ht_threshold,
gm->sw_low_battery_lt_en,
gm->sw_low_battery_lt_threshold);
if (gm->sw_low_battery_ht_en == 1 && thd == thd3) {
mutex_lock(&gm->sw_low_battery_mutex);
gm->sw_low_battery_ht_en = 0;
gm->sw_low_battery_lt_en = 0;
mutex_unlock(&gm->sw_low_battery_mutex);
disable_shutdown_cond(gm, LOW_BAT_VOLT);
wakeup_fg_algo(gm, FG_INTR_VBAT2_H);
}
if (gm->sw_low_battery_lt_en == 1 && (thd == thd1 || thd == thd2)) {
mutex_lock(&gm->sw_low_battery_mutex);
gm->sw_low_battery_ht_en = 0;
gm->sw_low_battery_lt_en = 0;
mutex_unlock(&gm->sw_low_battery_mutex);
wakeup_fg_algo(gm, FG_INTR_VBAT2_L);
}
}
/* ============================================================ */
/* hw low battery interrupt handler */
/* ============================================================ */
static int sw_vbat_h_irq_handler(struct mtk_battery *gm)
{
bm_debug("[%s]\n", __func__);
gauge_set_property(GAUGE_PROP_EN_HIGH_VBAT_INTERRUPT, 0);
gauge_set_property(GAUGE_PROP_EN_LOW_VBAT_INTERRUPT, 0);
disable_shutdown_cond(gm, LOW_BAT_VOLT);
wakeup_fg_algo(gm, FG_INTR_VBAT2_H);
fg_int_event(gm, EVT_INT_VBAT_H);
sw_check_bat_plugout(gm);
return 0;
}
static irqreturn_t vbat_h_irq(int irq, void *data)
{
struct mtk_battery *gm = data;
if (fg_interrupt_check(gm) == false)
return IRQ_HANDLED;
sw_vbat_h_irq_handler(gm);
return IRQ_HANDLED;
}
static int sw_vbat_l_irq_handler(struct mtk_battery *gm)
{
bm_debug("[%s]\n", __func__);
gauge_set_property(GAUGE_PROP_EN_HIGH_VBAT_INTERRUPT, 0);
gauge_set_property(GAUGE_PROP_EN_LOW_VBAT_INTERRUPT, 0);
wakeup_fg_algo(gm, FG_INTR_VBAT2_L);
fg_int_event(gm, EVT_INT_VBAT_L);
sw_check_bat_plugout(gm);
return 0;
}
static irqreturn_t vbat_l_irq(int irq, void *data)
{
struct mtk_battery *gm = data;
if (fg_interrupt_check(gm) == false)
return IRQ_HANDLED;
sw_vbat_l_irq_handler(gm);
return IRQ_HANDLED;
}
/* ============================================================ */
/* nafg interrupt handler */
/* ============================================================ */
static int nafg_irq_handler(struct mtk_battery *gm)
{
struct mtk_gauge *gauge;
int nafg_en = 0;
signed int nafg_cnt = 0;
signed int nafg_dltv = 0;
signed int nafg_c_dltv = 0;
gauge = gm->gauge;
/* 1. Get SW Car value */
fg_int_event(gm, EVT_INT_NAFG_CHECK);
nafg_cnt = gauge_get_int_property(GAUGE_PROP_NAFG_CNT);
nafg_dltv = gauge_get_int_property(GAUGE_PROP_NAFG_DLTV);
nafg_c_dltv = gauge_get_int_property(GAUGE_PROP_NAFG_C_DLTV);
gauge->hw_status.nafg_cnt = nafg_cnt;
gauge->hw_status.nafg_dltv = nafg_dltv;
gauge->hw_status.nafg_c_dltv = nafg_c_dltv;
bm_err(
"[%s][cnt:%d dltv:%d cdltv:%d cdltvt:%d zcv:%d vbat:%d]\n",
__func__,
nafg_cnt,
nafg_dltv,
nafg_c_dltv,
gauge->hw_status.nafg_c_dltv_th,
gauge->hw_status.nafg_zcv,
gauge_get_int_property(GAUGE_PROP_BATTERY_VOLTAGE));
/* battery_dump_nag(); */
/* 2. Stop HW interrupt*/
gauge_set_nag_en(gm, nafg_en);
fg_int_event(gm, EVT_INT_NAFG);
/* 3. Notify fg daemon */
wakeup_fg_algo(gm, FG_INTR_NAG_C_DLTV);
get_monotonic_boottime(&gm->last_nafg_update_time);
return 0;
}
static irqreturn_t nafg_irq(int irq, void *data)
{
struct mtk_battery *gm = data;
if (fg_interrupt_check(gm) == false)
return IRQ_HANDLED;
nafg_irq_handler(gm);
return IRQ_HANDLED;
}
/* ============================================================ */
/* battery plug out interrupt handler */
/* ============================================================ */
static irqreturn_t bat_plugout_irq(int irq, void *data)
{
struct mtk_battery *gm = data;
int is_bat_exist;
is_bat_exist = gauge_get_int_property(GAUGE_PROP_BATTERY_EXIST);
bm_err("[%s]is_bat %d miss:%d\n",
__func__,
is_bat_exist, gm->plug_miss_count);
if (fg_interrupt_check(gm) == false)
return IRQ_HANDLED;
/* avoid battery plug status mismatch case*/
if (is_bat_exist == 1) {
fg_int_event(gm, EVT_INT_BAT_PLUGOUT);
gm->plug_miss_count++;
bm_err("[%s]is_bat %d miss:%d\n",
__func__,
is_bat_exist, gm->plug_miss_count);
if (gm->plug_miss_count >= 3) {
disable_gauge_irq(gm->gauge, BAT_PLUGOUT_IRQ);
bm_err("[%s]disable FG_BAT_PLUGOUT\n",
__func__);
gm->disable_plug_int = 1;
}
}
if (is_bat_exist == 0) {
gm->bs_data.bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
wakeup_fg_algo(gm, FG_INTR_BAT_PLUGOUT);
battery_update(gm);
fg_int_event(gm, EVT_INT_BAT_PLUGOUT);
kernel_power_off();
}
return IRQ_HANDLED;
}
/* ============================================================ */
/* zcv interrupt handler */
/* ============================================================ */
static irqreturn_t zcv_irq(int irq, void *data)
{
struct mtk_battery *gm = data;
int fg_coulomb = 0;
int zcv_intr_en = 0;
int zcv_intr_curr = 0;
int zcv;
if (fg_interrupt_check(gm) == false)
return IRQ_HANDLED;
fg_coulomb = gauge_get_int_property(GAUGE_PROP_COULOMB);
zcv_intr_curr = gauge_get_int_property(GAUGE_PROP_ZCV_CURRENT);
zcv = gauge_get_int_property(GAUGE_PROP_ZCV);
bm_err("[%s] car:%d zcv_curr:%d zcv:%d, slp_cur_avg:%d\n",
__func__,
fg_coulomb, zcv_intr_curr, zcv,
gm->fg_cust_data.sleep_current_avg);
if (abs(zcv_intr_curr) < gm->fg_cust_data.sleep_current_avg) {
wakeup_fg_algo(gm, FG_INTR_FG_ZCV);
zcv_intr_en = 0;
gauge_set_property(GAUGE_PROP_ZCV_INTR_EN, zcv_intr_en);
}
fg_int_event(gm, EVT_INT_ZCV);
sw_check_bat_plugout(gm);
return IRQ_HANDLED;
}
/* ============================================================ */
/* battery cycle interrupt handler */
/* ============================================================ */
void fg_sw_bat_cycle_accu(struct mtk_battery *gm)
{
int diff_car = 0, tmp_car = 0, tmp_ncar = 0, tmp_thr = 0;
int fg_coulomb = 0, gauge_version;
fg_coulomb = gauge_get_int_property(GAUGE_PROP_COULOMB);
tmp_car = gm->bat_cycle_car;
tmp_ncar = gm->bat_cycle_ncar;
diff_car = fg_coulomb - gm->bat_cycle_car;
if (diff_car > 0) {
bm_err("[%s]drop diff_car\n", __func__);
gm->bat_cycle_car = fg_coulomb;
} else {
gm->bat_cycle_ncar = gm->bat_cycle_ncar + abs(diff_car);
gm->bat_cycle_car = fg_coulomb;
}
gauge_set_property(GAUGE_PROP_HW_INFO, 0);
bm_err("[%s]car[o:%d n:%d],diff_car:%d,ncar[o:%d n:%d hw:%d] thr %d\n",
__func__,
tmp_car, fg_coulomb, diff_car,
tmp_ncar, gm->bat_cycle_ncar, gm->gauge->fg_hw_info.ncar,
gm->bat_cycle_thr);
gauge_version = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
if (gauge_version >= GAUGE_HW_V1000 &&
gauge_version < GAUGE_HW_V2000) {
if (gm->bat_cycle_thr > 0 &&
gm->bat_cycle_ncar >= gm->bat_cycle_thr) {
tmp_ncar = gm->bat_cycle_ncar;
tmp_thr = gm->bat_cycle_thr;
gm->bat_cycle_ncar = 0;
wakeup_fg_algo(gm, FG_INTR_BAT_CYCLE);
bm_err("[fg_cycle_int_handler] ncar:%d thr:%d\n",
tmp_ncar, tmp_thr);
}
}
}
static irqreturn_t cycle_irq(int irq, void *data)
{
struct mtk_battery *gm = data;
if (fg_interrupt_check(gm) == false)
return IRQ_HANDLED;
disable_gauge_irq(gm->gauge, FG_N_CHARGE_L_IRQ);
wakeup_fg_algo(gm, FG_INTR_BAT_CYCLE);
fg_int_event(gm, EVT_INT_BAT_CYCLE);
sw_check_bat_plugout(gm);
return IRQ_HANDLED;
}
/* ============================================================ */
/* hw iavg interrupt handler */
/* ============================================================ */
static irqreturn_t iavg_h_irq(int irq, void *data)
{
struct mtk_battery *gm = data;
if (fg_interrupt_check(gm) == false)
return IRQ_HANDLED;
gm->gauge->hw_status.iavg_intr_flag = 0;
disable_gauge_irq(gm->gauge, FG_IAVG_H_IRQ);
disable_gauge_irq(gm->gauge, FG_IAVG_L_IRQ);
bm_debug("[%s]iavg_intr_flag %d\n",
__func__,
gm->gauge->hw_status.iavg_intr_flag);
wakeup_fg_algo(gm, FG_INTR_IAVG);
fg_int_event(gm, EVT_INT_IAVG);
sw_check_bat_plugout(gm);
return IRQ_HANDLED;
}
static irqreturn_t iavg_l_irq(int irq, void *data)
{
struct mtk_battery *gm = data;
if (fg_interrupt_check(gm) == false)
return IRQ_HANDLED;
gm->gauge->hw_status.iavg_intr_flag = 0;
disable_gauge_irq(gm->gauge, FG_IAVG_H_IRQ);
disable_gauge_irq(gm->gauge, FG_IAVG_L_IRQ);
bm_debug("[%s]iavg_intr_flag %d\n",
__func__,
gm->gauge->hw_status.iavg_intr_flag);
wakeup_fg_algo(gm, FG_INTR_IAVG);
fg_int_event(gm, EVT_INT_IAVG);
sw_check_bat_plugout(gm);
return IRQ_HANDLED;
}
/* ============================================================ */
/* bat temp interrupt handler */
/* ============================================================ */
static irqreturn_t bat_temp_irq(int irq, void *data)
{
struct mtk_battery *gm = data;
if (fg_interrupt_check(gm) == false)
return IRQ_HANDLED;
bm_debug("[%s]\n", __func__);
fg_bat_temp_int_internal(gm);
return IRQ_HANDLED;
}
/* ============================================================ */
/* charge full interrupt handler */
/* ============================================================ */
void notify_fg_chr_full(struct mtk_battery *gm)
{
struct timespec now_time, difftime;
get_monotonic_boottime(&now_time);
difftime = timespec_sub(now_time, gm->chr_full_handler_time);
if (now_time.tv_sec <= 10 || difftime.tv_sec >= 10) {
gm->chr_full_handler_time = now_time;
bm_err("[fg_chr_full_int_handler]\n");
wakeup_fg_algo(gm, FG_INTR_CHR_FULL);
fg_int_event(gm, EVT_INT_CHR_FULL);
}
}
/* ============================================================ */
/* sw iavg */
/* ============================================================ */
static void sw_iavg_init(struct mtk_battery *gm)
{
int bat_current = 0;
get_monotonic_boottime(&gm->sw_iavg_time);
gm->sw_iavg_car = gauge_get_int_property(GAUGE_PROP_COULOMB);
/* BAT_DISCHARGING = 0 */
/* BAT_CHARGING = 1 */
bat_current = gauge_get_int_property(GAUGE_PROP_BATTERY_CURRENT);
gm->sw_iavg = bat_current;
gm->sw_iavg_ht = gm->sw_iavg + gm->sw_iavg_gap;
gm->sw_iavg_lt = gm->sw_iavg - gm->sw_iavg_gap;
bm_err("%s %d, current:%d\n", __func__, gm->sw_iavg, bat_current);
}
void fg_update_sw_iavg(struct mtk_battery *gm)
{
struct timespec now_time, diff;
int fg_coulomb;
int version;
get_monotonic_boottime(&now_time);
diff = timespec_sub(now_time, gm->sw_iavg_time);
bm_debug("[%s]diff time:%ld\n",
__func__,
diff.tv_sec);
if (diff.tv_sec >= 60) {
fg_coulomb = gauge_get_int_property(GAUGE_PROP_COULOMB);
gm->sw_iavg = (fg_coulomb - gm->sw_iavg_car)
* 3600 / diff.tv_sec;
gm->sw_iavg_time = now_time;
gm->sw_iavg_car = fg_coulomb;
version = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
if (gm->sw_iavg >= gm->sw_iavg_ht
|| gm->sw_iavg <= gm->sw_iavg_lt) {
gm->sw_iavg_ht = gm->sw_iavg + gm->sw_iavg_gap;
gm->sw_iavg_lt = gm->sw_iavg - gm->sw_iavg_gap;
if (version < GAUGE_HW_V2000)
wakeup_fg_algo(gm, FG_INTR_IAVG);
}
bm_debug("[%s]time:%ld car:%d %d iavg:%d ht:%d lt:%d gap:%d\n",
__func__,
diff.tv_sec, fg_coulomb, gm->sw_iavg_car, gm->sw_iavg,
gm->sw_iavg_ht, gm->sw_iavg_lt, gm->sw_iavg_gap);
}
}
int wakeup_fg_daemon(unsigned int flow_state, int cmd, int para1)
{
static struct mtk_battery *gm;
char intr_name[32];
if (gm == NULL)
gm = get_mtk_battery();
if (gm->fgd_pid != 0) {
struct fgd_nl_msg_t *fgd_msg;
int size = FGD_NL_HDR_LEN + sizeof(flow_state);
if (size > (PAGE_SIZE << 1))
fgd_msg = vmalloc(size);
else {
if (in_interrupt())
fgd_msg = kmalloc(size, GFP_ATOMIC);
else
fgd_msg = kmalloc(size, GFP_KERNEL);
}
if (fgd_msg == NULL) {
if (size > PAGE_SIZE)
fgd_msg = vmalloc(size);
if (fgd_msg == NULL)
return -1;
}
Intr_Number_to_Name(intr_name, flow_state);
bm_debug("[%s] malloc size=%d pid=%d cmd:[%s],0x%x,cmd:%d,para1:%d\n",
__func__,
size, gm->fgd_pid, intr_name, flow_state, cmd, para1);
memset(fgd_msg, 0, size);
fgd_msg->fgd_cmd = FG_DAEMON_CMD_NOTIFY_DAEMON;
fgd_msg->fgd_subcmd = cmd;
fgd_msg->fgd_subcmd_para1 = para1;
memcpy(fgd_msg->fgd_data, &flow_state, sizeof(flow_state));
fgd_msg->fgd_data_len += sizeof(flow_state);
mtk_battery_send_to_user(gm, 0, fgd_msg);
kvfree(fgd_msg);
return 0;
} else
return -1;
}
void fg_drv_update_daemon(struct mtk_battery *gm)
{
int fg_current_iavg = 0;
bool valid = 0;
fg_update_sw_iavg(gm);
fg_nafg_monitor(gm);
fg_current_iavg = gauge_get_average_current(gm, &valid);
bm_err("[%s]ui_ht_gap:%d ui_lt_gap:%d sw_iavg:%d %d %d nafg_m:%d %d %d\n",
__func__,
gm->uisoc_int_ht_gap, gm->uisoc_int_lt_gap,
gm->sw_iavg, fg_current_iavg, valid,
gm->last_nafg_cnt, gm->is_nafg_broken, gm->disable_nafg_int);
wakeup_fg_algo_cmd(
gm,
FG_INTR_KERNEL_CMD,
FG_KERNEL_CMD_DUMP_REGULAR_LOG,
0);
}
static void mtk_battery_shutdown(struct mtk_battery *gm)
{
int fg_coulomb = 0;
int shut_car_diff = 0;
int verify_car;
fg_coulomb = gauge_get_int_property(GAUGE_PROP_COULOMB);
if (gm->d_saved_car != 0) {
shut_car_diff = fg_coulomb - gm->d_saved_car;
gauge_set_property(GAUGE_PROP_SHUTDOWN_CAR, shut_car_diff);
/* ready for writing to PMIC_RG */
}
verify_car = gauge_get_int_property(GAUGE_PROP_SHUTDOWN_CAR);
bm_err("******** %s!! car=[o:%d,new:%d,diff:%d v:%d]********\n",
__func__,
gm->d_saved_car, fg_coulomb, shut_car_diff, verify_car);
}
void enable_bat_temp_det(bool en)
{
gauge_set_property(GAUGE_PROP_BAT_TEMP_FROZE_EN, !en);
}
static int mtk_battery_suspend(struct mtk_battery *gm, pm_message_t state)
{
int version;
bm_err("******** %s!! iavg=%d ***GM3 disable:%d %d %d %d tmp_intr:%d***\n",
__func__,
gm->gauge->hw_status.iavg_intr_flag,
gm->disableGM30,
gm->fg_cust_data.disable_nafg,
gm->ntc_disable_nafg,
gm->cmd_disable_nafg,
gm->enable_tmp_intr_suspend);
if (gm->enable_tmp_intr_suspend == 0) {
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_LT, 0);
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_HT, 0);
enable_bat_temp_det(0);
}
version = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
if (version >= GAUGE_HW_V2000
&& gm->gauge->hw_status.iavg_intr_flag == 1) {
disable_gauge_irq(gm->gauge, FG_IAVG_H_IRQ);
if (gm->gauge->hw_status.iavg_lt > 0)
disable_gauge_irq(gm->gauge, FG_IAVG_L_IRQ);
}
return 0;
}
static int mtk_battery_resume(struct mtk_battery *gm)
{
int version;
bm_err("******** %s!! iavg=%d ***GM3 disable:%d %d %d %d***\n",
__func__,
gm->gauge->hw_status.iavg_intr_flag,
gm->disableGM30,
gm->fg_cust_data.disable_nafg,
gm->ntc_disable_nafg,
gm->cmd_disable_nafg);
version = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
if (version >=
GAUGE_HW_V2000
&& gm->gauge->hw_status.iavg_intr_flag == 1) {
enable_gauge_irq(gm->gauge, FG_IAVG_H_IRQ);
if (gm->gauge->hw_status.iavg_lt > 0)
enable_gauge_irq(gm->gauge, FG_IAVG_L_IRQ);
}
/* reset nafg monitor time to avoid suspend for too long case */
get_monotonic_boottime(&gm->last_nafg_update_time);
fg_update_sw_iavg(gm);
if (gm->enable_tmp_intr_suspend == 0) {
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_LT, 1);
gauge_set_property(GAUGE_PROP_EN_BAT_TMP_HT, 1);
enable_bat_temp_det(1);
}
return 0;
}
bool is_daemon_support(struct mtk_battery *gm)
{
bool is_support = true;
pr_notice("%s: is_support = %d\n", __func__, is_support);
return is_support;
}
int mtk_battery_daemon_init(struct platform_device *pdev)
{
int ret;
int hw_version;
struct mtk_battery *gm;
struct mtk_gauge *gauge;
struct fuel_gauge_custom_data *fg_cust_data;
gauge = dev_get_drvdata(&pdev->dev);
gm = gauge->gm;
if (is_daemon_support(gm) == false)
return -EIO;
if (gm->mtk_battery_sk == NULL) {
bm_err("[%s]netlink_kernel_create error\n", __func__);
return -EIO;
}
gm->pl_two_sec_reboot = gauge_get_int_property(GAUGE_PROP_2SEC_REBOOT);
gauge_set_property(GAUGE_PROP_2SEC_REBOOT, 0);
hw_version = gauge_get_int_property(GAUGE_PROP_HW_VERSION);
gm->shutdown = mtk_battery_shutdown;
gm->suspend = mtk_battery_suspend;
gm->resume = mtk_battery_resume;
fg_cust_data = &gm->fg_cust_data;
if (hw_version == GAUGE_NO_HW) {
gm->gauge->sw_nafg_irq = nafg_irq_handler;
gm->gauge->sw_vbat_h_irq = sw_vbat_h_irq_handler;
gm->gauge->sw_vbat_l_irq = sw_vbat_l_irq_handler;
}
if (hw_version >= GAUGE_HW_V0500) {
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[ZCV_IRQ],
NULL, zcv_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_gauge_zcv",
gm);
if (hw_version == GAUGE_HW_V0500) {
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[VBAT_H_IRQ],
NULL, vbat_h_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_gauge_vbat_high",
gm);
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[VBAT_L_IRQ],
NULL, vbat_l_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_gauge_vbat_low",
gm);
}
}
if (hw_version >= GAUGE_HW_V1000) {
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[NAFG_IRQ],
NULL, nafg_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_gauge_nafg",
gm);
if (hw_version < GAUGE_HW_V2000) {
#if IS_ENABLED(CONFIG_PMIC_LBAT_SERVICE)
gm->lowbat_service =
lbat_user_register("fuel gauge",
fg_cust_data->vbat2_det_voltage3 / 10,
fg_cust_data->vbat2_det_voltage1 / 10,
fg_cust_data->vbat2_det_voltage2 / 10,
fg_update_sw_low_battery_check);
bm_err("[%s]lbat user_register done, %d,%d,%d\n",
__func__, fg_cust_data->vbat2_det_voltage3,
fg_cust_data->vbat2_det_voltage1,
fg_cust_data->vbat2_det_voltage2);
if (gm->lowbat_service != NULL) {
lbat_user_set_debounce(gm->lowbat_service,
fg_cust_data->vbat2_det_time * 1000,
fg_cust_data->vbat2_det_counter,
fg_cust_data->vbat2_det_time * 1000,
fg_cust_data->vbat2_det_counter);
bm_err("[%s]lbat set_debounce,time:%d,counter:%d\n",
__func__, fg_cust_data->vbat2_det_time,
fg_cust_data->vbat2_det_counter);
} else
bm_err("[%s]lowbat_service null\n", __func__);
#endif /* end of CONFIG_PMIC_LBAT_SERVICE */
/* sw bat_cycle_car init, gm25 should start from 0 */
gm->bat_cycle_car =
gauge_get_int_property(GAUGE_PROP_COULOMB);
if (gm->bat_cycle_car < 0)
gm->bat_cycle_car = 0;
}
}
if (hw_version >= GAUGE_HW_V2000) {
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[BAT_PLUGOUT_IRQ],
NULL, bat_plugout_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_gauge_bat_plugout",
gm);
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[FG_N_CHARGE_L_IRQ],
NULL, cycle_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_cycle_zcv",
gm);
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[FG_IAVG_H_IRQ],
NULL, iavg_h_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_gauge_iavg_h",
gm);
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[FG_IAVG_L_IRQ],
NULL, iavg_l_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_gauge_iavg_l",
gm);
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[BAT_TMP_H_IRQ],
NULL, bat_temp_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_bat_tmp_h",
gm);
ret = devm_request_threaded_irq(&gm->gauge->pdev->dev,
gm->gauge->irq_no[BAT_TMP_L_IRQ],
NULL, bat_temp_irq,
IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
"mtk_bat_tmp_l",
gm);
}
sw_iavg_init(gm);
mtk_battery_setup_files(pdev);
return 0;
}