[u-boot] fuel gauge: rk816: optimize some problems

1. check dc by pmic;
    2. rename some register;
    3. init rsoc only when charging in uboot

Change-Id: Ia046276c5849c7813cc78aba99ac7f7f52290d8f
Signed-off-by: Firefly <service@t-firefly.com>
(cherry picked from commit f6b2c82f17b536f983679fc18b1ee0eccf9a004f)
This commit is contained in:
Firefly
2016-05-05 17:41:26 +08:00
committed by cjp
parent f5643dd770
commit a31d823018
2 changed files with 95 additions and 94 deletions

176
u-boot/drivers/power/fuel_gauge/fg_rk816.c Executable file → Normal file
View File

@ -16,7 +16,7 @@
DECLARE_GLOBAL_DATA_PTR;
static int dbg_enable;
static int dbg_enable = 0;
#define DBG(args...) \
do { \
if (dbg_enable) { \
@ -24,7 +24,8 @@ static int dbg_enable;
} \
} while (0)
#define BAT_INFO(fmt, args...) printf("rk816-bat: "fmt, ##args)
#define BAT_INFO(fmt, args...) printf("rk816-bat: "fmt, ##args)
#define DRIVER_VERSION "1.0"
/* THERMAL_REG */
#define TEMP_105C (0x02 << 2)
@ -252,19 +253,19 @@ static void rk816_bat_set_vol_instant_mode(struct battery_info *di)
{
u8 val;
val = rk816_bat_read(RK816_GGSTS);
val = rk816_bat_read(RK816_GGSTS_REG);
val |= VOL_INSTANT;
rk816_bat_write(RK816_GGSTS, val);
rk816_bat_write(RK816_GGSTS_REG, val);
}
static void rk816_bat_set_vol_avg_mode(struct battery_info *di)
{
u8 val;
val = rk816_bat_read(RK816_GGSTS);
val = rk816_bat_read(RK816_GGSTS_REG);
val &= ~0x01;
val |= VOL_AVG;
rk816_bat_write(RK816_GGSTS, val);
rk816_bat_write(RK816_GGSTS_REG, val);
}
static void rk816_bat_enable_gauge(struct battery_info *di)
@ -420,7 +421,7 @@ static void rk816_bat_init_chrg_config(struct battery_info *di)
rk816_bat_select_chrg_cv(di);
finish_ma = rk816_bat_finish_ma(di->fcc);
ggcon = rk816_bat_read(RK816_GGCON);
ggcon = rk816_bat_read(RK816_GGCON_REG);
sup_sts = rk816_bat_read(RK816_SUP_STS_REG);
usb_ctrl = rk816_bat_read(RK816_USB_CTRL_REG);
thermal = rk816_bat_read(RK816_THERMAL_REG);
@ -454,7 +455,7 @@ static void rk816_bat_init_chrg_config(struct battery_info *di)
/* adc current mode */
ggcon |= ADC_CUR_MODE;
rk816_bat_write(RK816_GGCON, ggcon);
rk816_bat_write(RK816_GGCON_REG, ggcon);
rk816_bat_write(RK816_SUP_STS_REG, sup_sts);
rk816_bat_write(RK816_USB_CTRL_REG, usb_ctrl);
rk816_bat_write(RK816_THERMAL_REG, thermal);
@ -590,10 +591,10 @@ static int rk816_bat_get_coulomb_cap(struct battery_info *di)
{
int val = 0;
val |= rk816_bat_read(RK816_GASCNT3) << 24;
val |= rk816_bat_read(RK816_GASCNT2) << 16;
val |= rk816_bat_read(RK816_GASCNT1) << 8;
val |= rk816_bat_read(RK816_GASCNT0) << 0;
val |= rk816_bat_read(RK816_GASCNT_REG3) << 24;
val |= rk816_bat_read(RK816_GASCNT_REG2) << 16;
val |= rk816_bat_read(RK816_GASCNT_REG1) << 8;
val |= rk816_bat_read(RK816_GASCNT_REG0) << 0;
val /= 2390;
return val;
@ -623,22 +624,6 @@ static void rk816_bat_init_capacity(struct battery_info *di, u32 capacity)
di->rsoc = rk816_bat_get_rsoc(di);
}
static void rk816_bat_first_pwron(struct battery_info *di)
{
int ocv_vol;
rk816_bat_save_fcc(di, di->design_cap);
ocv_vol = rk816_bat_get_ocv_voltage(di);
di->fcc = rk816_bat_get_fcc(di);
di->nac = rk816_bat_vol_to_cap(di, ocv_vol);
di->rsoc = rk816_bat_vol_to_soc(di, ocv_vol);
di->dsoc = di->rsoc;
rk816_bat_init_capacity(di, di->nac);
di->rsoc = rk816_bat_get_rsoc(di);
BAT_INFO("first power on: soc=%d\n", di->dsoc);
}
static bool is_rk816_bat_ocv_valid(struct battery_info *di)
{
return rk816_bat_get_pwroff_min(di) >= 30 ? true : false;
@ -650,7 +635,10 @@ static int rk816_bat_get_usb_state(struct battery_info *di)
switch (dwc_otg_check_dpdm()) {
case 0:
charger_type = NO_CHARGER;
if ((rk816_bat_read(RK816_VB_MON_REG) & PLUG_IN_STS) != 0)
charger_type = DC_CHARGER;
else
charger_type = NO_CHARGER;
break;
case 1:
case 3:
@ -666,26 +654,47 @@ static int rk816_bat_get_usb_state(struct battery_info *di)
return charger_type;
}
static void rk816_bat_set_initialized_state(struct battery_info *di)
static void rk816_bat_clr_initialized_state(struct battery_info *di)
{
u8 val;
int vol, charger;
val = rk816_bat_read(RK816_MISC_MARK_REG);
val &= ~0x08;
rk816_bat_write(RK816_MISC_MARK_REG, val);
vol = rk816_bat_get_est_voltage(di);
charger = rk816_bat_get_usb_state(di);
}
static void rk816_bat_set_initialized_state(struct battery_info *di)
{
#ifdef CONFIG_UBOOT_CHARGE
if ((vol < CONFIG_SYSTEM_ON_VOL_THRESD) || (charger != NO_CHARGER)) {
u8 val;
if (rk816_bat_get_usb_state(di) != NO_CHARGER) {
val |= 0x08;
rk816_bat_write(RK816_MISC_MARK_REG, val);
BAT_INFO("rk816 fuel gauge initialized... estv=%d, ch=%d\n",
vol, charger);
BAT_INFO("fuel gauge initialized... estv=%d, ch=%d\n",
rk816_bat_get_est_voltage(di),
rk816_bat_get_usb_state(di));
}
#endif
}
static void rk816_bat_first_pwron(struct battery_info *di)
{
int ocv_vol;
rk816_bat_save_fcc(di, di->design_cap);
ocv_vol = rk816_bat_get_ocv_voltage(di);
di->fcc = rk816_bat_get_fcc(di);
di->nac = rk816_bat_vol_to_cap(di, ocv_vol);
di->rsoc = rk816_bat_vol_to_soc(di, ocv_vol);
di->dsoc = di->rsoc;
rk816_bat_init_capacity(di, di->nac);
di->rsoc = rk816_bat_get_rsoc(di);
rk816_bat_set_initialized_state(di);
BAT_INFO("first power on: soc=%d\n", di->dsoc);
}
static void rk816_bat_not_first_pwron(struct battery_info *di)
{
u8 init_soc;
@ -694,12 +703,15 @@ static void rk816_bat_not_first_pwron(struct battery_info *di)
di->fcc = rk816_bat_get_fcc(di);
init_soc = rk816_bat_get_dsoc(di);
prev_cap = rk816_bat_get_prev_cap(di);
di->pwroff_min = rk816_bat_get_pwroff_min(di);
if (is_rk816_bat_ocv_valid(di)) {
ocv_vol = rk816_bat_get_ocv_voltage(di);
ocv_soc = rk816_bat_vol_to_soc(di, ocv_vol);
ocv_cap = rk816_bat_vol_to_cap(di, ocv_vol);
prev_cap = ocv_cap;
BAT_INFO("do ocv calib.. rsoc=%d\n", ocv_soc);
if (abs(ocv_soc - init_soc) >= di->max_soc_offset) {
BAT_INFO("trigger max soc offset, soc: %d -> %d\n",
init_soc, ocv_soc);
@ -711,11 +723,11 @@ static void rk816_bat_not_first_pwron(struct battery_info *di)
di->nac = prev_cap;
rk816_bat_init_capacity(di, di->nac);
rk816_bat_set_initialized_state(di);
BAT_INFO("dl=%d rl=%d cap=%d m=%d v=%d ov=%d c=%d pl=%d ch=%d\n",
BAT_INFO("dl=%d rl=%d cap=%d m=%d v=%d ov=%d c=%d pl=%d ch=%d Ver=%s\n",
di->dsoc, di->rsoc, di->remain_cap, di->pwroff_min,
rk816_bat_get_avg_voltage(di), rk816_bat_get_ocv_voltage(di),
rk816_bat_get_avg_current(di), rk816_bat_get_dsoc(di),
rk816_bat_get_usb_state(di)
rk816_bat_get_usb_state(di), DRIVER_VERSION
);
}
@ -723,10 +735,10 @@ static bool is_rk816_bat_first_poweron(struct battery_info *di)
{
u8 buf;
buf = rk816_bat_read(RK816_GGSTS);
buf = rk816_bat_read(RK816_GGSTS_REG);
if (buf & BAT_CON) {
buf &= ~(BAT_CON);
rk816_bat_write(RK816_GGSTS, buf);
rk816_bat_write(RK816_GGSTS_REG, buf);
return true;
}
@ -749,14 +761,12 @@ static bool rk816_bat_ocv_sw_reset(struct battery_info *di)
return false;
}
static int rk816_bat_init_rsoc(struct battery_info *di)
void rk816_bat_init_rsoc(struct battery_info *di)
{
if (is_rk816_bat_first_poweron(di) || rk816_bat_ocv_sw_reset(di))
rk816_bat_first_pwron(di);
else
rk816_bat_not_first_pwron(di);
return 0;
}
static int rk816_bat_calc_linek(struct battery_info *di)
@ -769,7 +779,7 @@ static int rk816_bat_calc_linek(struct battery_info *di)
di->old_remain_cap = di->remain_cap;
delta = abs(di->dsoc - di->rsoc);
diff = delta * 2;
diff = delta * 3;
di->meet_soc = (di->dsoc >= di->rsoc) ?
(di->dsoc + diff) : (di->rsoc + diff);
@ -813,9 +823,13 @@ static void rk816_bat_fg_init(struct battery_info *di)
rk816_bat_set_vol_instant_mode(di);
rk816_bat_init_voltage_kb(di);
rk816_bat_init_poffset(di);
rk816_bat_init_rsoc(di);
rk816_bat_clr_initialized_state(di);
#ifdef CONFIG_UBOOT_CHARGE
/* if not keep charge in uboot, skip rsoc initial, done by kernel */
if (rk816_bat_get_usb_state(di) != NO_CHARGER)
rk816_bat_init_rsoc(di);
#endif
rk816_bat_init_chrg_config(di);
di->voltage_avg = rk816_bat_get_avg_voltage(di);
di->voltage_ocv = rk816_bat_get_ocv_voltage(di);
di->current_avg = rk816_bat_get_avg_current(di);
@ -853,7 +867,7 @@ static void rk816_bat_charger_setting(struct battery_info *di, int charger)
else if (charger == DC_CHARGER || charger == AC_CHARGER)
rk816_bat_set_current(di->chrg_cur_input);
else
printf("rk816 charger setting error %d\n", charger);
BAT_INFO("charger setting error %d\n", charger);
old_charger = charger;
}
@ -905,7 +919,7 @@ static int rk816_bat_check(struct pmic *p, struct pmic *bat)
return 0;
}
static int rk816_bat_save_dsoc(struct battery_info *di, u8 save_soc)
static void rk816_bat_save_dsoc(struct battery_info *di, u8 save_soc)
{
static u8 old_soc;
@ -913,8 +927,6 @@ static int rk816_bat_save_dsoc(struct battery_info *di, u8 save_soc)
old_soc = save_soc;
rk816_bat_write(RK816_SOC_REG, save_soc);
}
return 0;
}
static void rk816_bat_save_cap(struct battery_info *di, int cap)
@ -1002,41 +1014,44 @@ static void rk816_bat_debug_info(struct battery_info *di)
{
u8 sup_sts, ggcon, ggsts, vb_mod, rtc, thermal, misc;
u8 usb_ctrl, chrg_ctrl1, chrg_ctrl2, chrg_ctrl3;
const char *name[] = {"NONE", "USB", "AC", "DC", "UNDEF"};
if (!dbg_enable)
return;
ggcon = rk816_bat_read(RK816_GGCON);
ggsts = rk816_bat_read(RK816_GGSTS);
ggcon = rk816_bat_read(RK816_GGCON_REG);
ggsts = rk816_bat_read(RK816_GGSTS_REG);
sup_sts = rk816_bat_read(RK816_SUP_STS_REG);
usb_ctrl = rk816_bat_read(RK816_USB_CTRL_REG);
thermal = rk816_bat_read(RK816_THERMAL_REG);
vb_mod = rk816_bat_read(RK816_VB_MON_REG);
misc = rk816_bat_read(RK816_MISC_MARK_REG);
rtc = rk816_bat_read(0x00);
rtc = rk816_bat_read(RK816_SECONDS_REG);
chrg_ctrl1 = rk816_bat_read(RK816_CHRG_CTRL_REG1);
chrg_ctrl2 = rk816_bat_read(RK816_CHRG_CTRL_REG2);
chrg_ctrl3 = rk816_bat_read(RK816_CHRG_CTRL_REG3);
DBG("\n------------- dump_debug_regs -----------------\n"
"GGCON=0x%2x, GGSTS=0x%2x, RTC=0x%2x\n"
"SUP_STS= 0x%2x, VB_MOD=0x%2x, USB_CTRL=0x%2x\n"
"THERMAL=0x%2x, MISC_MARK=0x%2x\n"
DBG("\n---------------------- DEBUG REGS ------------------------\n"
"GGCON=0x%2x, GGSTS=0x%2x, RTC=0x%2x, SUP_STS= 0x%2x\n"
"VB_MOD=0x%2x, USB_CTRL=0x%2x, THERMAL=0x%2x, MISC=0x%2x\n"
"CHRG_CTRL:REG1=0x%2x, REG2=0x%2x, REG3=0x%2x\n",
ggcon, ggsts, rtc, sup_sts, vb_mod, usb_ctrl,
thermal, misc, chrg_ctrl1, chrg_ctrl2, chrg_ctrl3
);
DBG("--------------------------------------------------\n"
"Vavg=%d, Iavg=%d, Fcc=%d, Cap=%d, Vocv=%d\n"
"dsoc=%d, rsoc=%d, charger=%d, vk=%d, vb=%d, meet=%d\n"
"old_cap = %d\n",
rk816_bat_get_avg_voltage(di), rk816_bat_get_avg_current(di),
di->fcc, di->remain_cap, rk816_bat_get_ocv_voltage(di),
di->dsoc, rk816_bat_get_rsoc(di), rk816_fg.di.state_of_chrg,
di->voltage_k, di->voltage_b, di->meet_soc, di->old_remain_cap
);
);
DBG("----------------------------------------------------------\n"
"Dsoc=%d, Rsoc=%d, Vavg=%d, Iavg=%d, Cap=%d, Fcc=%d\n"
"K=%d, old_cap=%d, charger=%s, Is=%d, Ip=%d, Vs=%d\n"
"min=%d, meet: soc=%d, calc: dsoc=%d, rsoc=%d, Vocv=%d\n",
di->dsoc, rk816_bat_get_rsoc(di), rk816_bat_get_avg_voltage(di),
rk816_bat_get_avg_current(di), di->remain_cap, di->fcc,
di->linek, di->old_remain_cap, name[rk816_fg.di.state_of_chrg],
CHRG_CUR_SEL[chrg_ctrl1 & 0x0f], CHRG_CUR_INPUT[usb_ctrl & 0x0f],
CHRG_VOL_SEL[(chrg_ctrl1 & 0x70) >> 4], di->pwroff_min,
di->meet_soc, di->calc_dsoc, di->calc_rsoc,
rk816_bat_get_ocv_voltage(di)
);
rk816_bat_get_chrg_status(di);
DBG("###################################################\n");
DBG("###########################################################\n");
}
static bool is_rk816_bat_need_term_chrg(struct battery_info *di)
@ -1212,29 +1227,14 @@ static int rk816_bat_parse_dt(struct battery_info *di, void const *blob)
return -EINVAL;
}
di->dts_vol_sel = fdtdec_get_int(blob, node, "max_chrg_voltage", -1);
if (di->chrg_vol_sel) {
printf("read max_chrg_voltage error\n");
return -EINVAL;
}
di->dts_cur_input = fdtdec_get_int(blob, node, "max_input_current", -1);
if (di->chrg_vol_sel) {
printf("read max_input_current error\n");
return -EINVAL;
}
di->dts_cur_sel = fdtdec_get_int(blob, node, "max_chrg_current", -1);
if (di->chrg_vol_sel) {
printf("read max_chrg_current error\n");
return -EINVAL;
}
di->dts_vol_sel = fdtdec_get_int(blob, node, "max_chrg_voltage", 4200);
di->dts_cur_input = fdtdec_get_int(blob, node, "max_input_current", 2000);
di->dts_cur_sel = fdtdec_get_int(blob, node, "max_chrg_current", 1200);
di->max_soc_offset = fdtdec_get_int(blob, node, "max_soc_offset", 70);
di->virtual_power = fdtdec_get_int(blob, node, "virtual_power", 0);
di->bat_res = fdtdec_get_int(blob, node, "bat_res", 135);
di->dc_det_adc = fdtdec_get_int(blob, node, "dc_det_adc", -1);
if (di->dc_det_adc < 0) {
di->dc_det_adc = fdtdec_get_int(blob, node, "dc_det_adc", 0);
if (di->dc_det_adc <= 0) {
if (!fdtdec_decode_gpio(blob, node,
"dc_det_gpio", &di->dc_det)) {
di->dc_det.flags =

View File

@ -14,6 +14,7 @@
#define RK816_NUM_REGULATORS 10
#define RK816_VOLT_MASK 0x3f
#define RK816_SECONDS_REG 0x00
/*VERSION REGISTER*/
#define RK816_CHIP_NAME_REG 0x17
@ -93,18 +94,18 @@
/*ADC AND FUEL GAUGE REGISTER*/
#define RK816_TS_CTRL_REG 0xAC
#define RK816_ADC_CTRL_REG 0xAD
#define RK816_GGCON 0xB0
#define RK816_GGSTS 0xB1
#define RK816_GGCON_REG 0xB0
#define RK816_GGSTS_REG 0xB1
#define RK816_ZERO_CUR_ADC_REGH 0xB2
#define RK816_ZERO_CUR_ADC_REGL 0xB3
#define RK816_GASCNT_CAL_REG3 0xB4
#define RK816_GASCNT_CAL_REG2 0xB5
#define RK816_GASCNT_CAL_REG1 0xB6
#define RK816_GASCNT_CAL_REG0 0xB7
#define RK816_GASCNT3 0xB8
#define RK816_GASCNT2 0xB9
#define RK816_GASCNT1 0xBA
#define RK816_GASCNT0 0xBB
#define RK816_GASCNT_REG3 0xB8
#define RK816_GASCNT_REG2 0xB9
#define RK816_GASCNT_REG1 0xBA
#define RK816_GASCNT_REG0 0xBB
#define RK816_BAT_CUR_AVG_REGH 0xBC
#define RK816_BAT_CUR_AVG_REGL 0xBD
#define RK816_TS_ADC_REGH 0xBE