summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshengfei Xu <xsf@rock-chips.com>2018-02-10 19:05:57 +0800
committerTao Huang <huangtao@rock-chips.com>2018-02-22 11:39:59 +0800
commit2c1c86dca03672433064faf67976c01a3b25e7f1 (patch)
tree5da7d3d7e55fd251e254dae0b421b695f68f311f
parent73403cf5b2cea690ea39982cc22a856215e50f60 (diff)
power: rk817: fix the battery charging but dispaly soc not up
Change-Id: I3153dad46c959670f11dd91c7cbd687f4136c171 Signed-off-by: shengfei Xu <xsf@rock-chips.com>
-rw-r--r--drivers/power/rk817_battery.c156
1 files changed, 136 insertions, 20 deletions
diff --git a/drivers/power/rk817_battery.c b/drivers/power/rk817_battery.c
index aa9163d62c40..ab3ef6a2599c 100644
--- a/drivers/power/rk817_battery.c
+++ b/drivers/power/rk817_battery.c
@@ -37,7 +37,7 @@
#include <linux/wakelock.h>
#include <linux/workqueue.h>
-static int dbg_enable;
+static int dbg_enable = 1;
module_param_named(dbg_level, dbg_enable, int, 0644);
@@ -495,6 +495,19 @@ struct rk817_battery_device {
int zero_linek;
u64 zero_drop_sec;
u64 shtd_drop_sec;
+
+ int powerpatch_res;
+ int zero_voltage_avg;
+ int zero_current_avg;
+ int zero_vsys;
+ int zero_dead_voltage;
+ int zero_dead_soc;
+ int zero_dead_cap;
+ int zero_batvol_to_ocv;
+ int zero_batocv_to_soc;
+ int zero_batocv_to_cap;
+ int zero_xsoc;
+
int sm_remain_cap;
int sm_linek;
int sm_chrg_dsoc;
@@ -1330,16 +1343,27 @@ static void rk817_bat_calc_sm_linek(struct rk817_battery_device *battery)
{
int linek;
int diff, delta;
+ int current_avg = rk817_bat_get_avg_current(battery);
delta = abs(battery->dsoc - battery->rsoc);
diff = delta * 3;/* speed:3/4 */
- if (battery->dsoc < battery->rsoc)
- linek = -1000 * diff / DIV(delta + diff);
- else if (battery->dsoc > battery->rsoc)
- linek = -1000 * (delta + diff) / DIV(diff);
- else
- linek = -1000;
+ if (current_avg > 0) {
+ if (battery->dsoc < battery->rsoc)
+ linek = 1000 * diff / DIV(delta + diff);
+ else if (battery->dsoc > battery->rsoc)
+ linek = 1000 * (delta + diff) / DIV(diff);
+ else
+ linek = 1000;
+ } else {
+ if (battery->dsoc < battery->rsoc)
+ linek = -1000 * diff / DIV(delta + diff);
+ else if (battery->dsoc > battery->rsoc)
+ linek = -1000 * (delta + diff) / DIV(diff);
+ else
+ linek = -1000;
+ }
+
battery->dbg_meet_soc = (battery->dsoc >= battery->rsoc) ?
(battery->dsoc - diff) : (battery->rsoc - diff);
@@ -1403,6 +1427,7 @@ static void rk817_bat_not_first_pwron(struct rk817_battery_device *battery)
battery->is_initialized = is_rk817_bat_initialized(battery);
battery->is_ocv_calib = is_rk817_bat_ocv_valid(battery);
+ pre_soc *= 1000;
if (battery->is_halt) {
BAT_INFO("system halt last time... cap: pre=%d, now=%d\n",
pre_cap, now_cap);
@@ -1448,7 +1473,7 @@ static void rk817_bat_not_first_pwron(struct rk817_battery_device *battery)
}
}
finish:
- battery->dsoc = pre_soc * 1000;
+ battery->dsoc = pre_soc;
battery->nac = pre_cap;
if (battery->nac < 0)
battery->nac = 0;
@@ -1784,8 +1809,8 @@ static void rk817_bat_power_supply_changed(struct rk817_battery_device *battery)
{
static int old_soc = -1;
- if (battery->dsoc > 100)
- battery->dsoc = 100;
+ if (battery->dsoc > 100 * 1000)
+ battery->dsoc = 100 * 1000;
else if (battery->dsoc < 0)
battery->dsoc = 0;
@@ -1828,8 +1853,6 @@ static void rk817_battery_debug_info(struct rk817_battery_device *battery)
rk817_bat_get_ocv_current(battery);
rk817_bat_get_ocv_current0(battery);
rk817_bat_get_pwron_current(battery);
- rk817_bat_init_coulomb_cap(battery, 500);
- rk817_bat_update_qmax(battery, 1000);
rk817_bat_get_ocv_count(battery);
rk817_bat_save_dsoc(battery, battery->dsoc);
DBG("capactiy = %d\n", rk817_bat_get_capacity_mah(battery));
@@ -1919,7 +1942,31 @@ static void rk817_bat_calc_smooth_dischrg(struct rk817_battery_device *battery)
static void rk817_bat_smooth_algorithm(struct rk817_battery_device *battery)
{
- int ydsoc = 0, delta_cap = 0, old_cap = 0;
+ int ydsoc = 0, delta_cap = 0, old_cap = 0, tmp_soc;
+ int linek;
+ int diff, delta;
+ int current_avg = rk817_bat_get_avg_current(battery);
+
+ delta = abs(battery->dsoc - battery->rsoc);
+ diff = delta * 3;/* speed:3/4 */
+
+ if (current_avg > 0) {
+ if (battery->dsoc < battery->rsoc)
+ linek = 1000 * diff / DIV(delta + diff);
+ else if (battery->dsoc > battery->rsoc)
+ linek = 1000 * (delta + diff) / DIV(diff);
+ else
+ linek = 1000;
+ } else {
+ if (battery->dsoc < battery->rsoc)
+ linek = -1000 * diff / DIV(delta + diff);
+ else if (battery->dsoc > battery->rsoc)
+ linek = -1000 * (delta + diff) / DIV(diff);
+ else
+ linek = -1000;
+ }
+
+ battery->sm_linek = linek;
battery->remain_cap = rk817_bat_get_capacity_uah(battery);
@@ -1931,7 +1978,7 @@ static void rk817_bat_smooth_algorithm(struct rk817_battery_device *battery)
/* from charge to discharge:
* remain_cap may be above sm_remain_cap, delta_cap <= 0
*/
- delta_cap = battery->sm_remain_cap - battery->remain_cap;
+ delta_cap = battery->remain_cap - battery->sm_remain_cap;
DBG("smooth: sm_remain_cap = %d, remain_cap = %d\n",
battery->sm_remain_cap, battery->remain_cap);
DBG("smooth: delta_cap = %d, dsoc = %d\n",
@@ -1943,7 +1990,7 @@ static void rk817_bat_smooth_algorithm(struct rk817_battery_device *battery)
}
/* discharge: sm_linek < 0, if delate_cap <0, ydsoc > 0 */
- ydsoc = battery->sm_linek * (delta_cap / DIV(battery->fcc)) / 10;
+ ydsoc = battery->sm_linek * abs(delta_cap / DIV(battery->fcc)) / 10;
DBG("smooth: ydsoc = %d, fcc = %d\n", ydsoc, battery->fcc);
if (ydsoc == 0) {
@@ -1961,8 +2008,26 @@ static void rk817_bat_smooth_algorithm(struct rk817_battery_device *battery)
* from charge status to dischrage
*/
battery->smooth_soc += ydsoc;
- if (ydsoc < 0)
+ if (ydsoc < 0) {
rk817_bat_calc_smooth_dischrg(battery);
+ } else {
+ if (battery->smooth_soc < 0)
+ battery->smooth_soc = 0;
+
+ tmp_soc = battery->smooth_soc / 1000;
+
+ if (tmp_soc != battery->dsoc / 1000) {
+ if (battery->smooth_soc < battery->dsoc)
+ return;
+ if (battery->smooth_soc > battery->dsoc + 1000)
+ battery->dsoc += 1000;
+ else
+ battery->dsoc = battery->smooth_soc;
+ if (battery->dsoc <= 0)
+ battery->dsoc = 0;
+ }
+ }
+
DBG("smooth: smooth_soc = %d, dsoc = %d\n",
battery->smooth_soc, battery->dsoc);
DBG("smooth: delta_cap = %d, dsoc = %d\n",
@@ -1991,6 +2056,10 @@ static void rk817_bat_calc_zero_linek(struct rk817_battery_device *battery)
powerpatch_res = (voltage_avg - vsys) * 1000 / current_avg;
+ battery->zero_voltage_avg = voltage_avg;
+ battery->zero_current_avg = current_avg;
+ battery->zero_vsys = vsys;
+
DBG("Zero: voltage_avg = %d, Vsys = %d\n", voltage_avg, vsys);
DBG("Zero: powerpatch_res = %d\n", powerpatch_res);
DBG("ZERO0: shtd_vol: poweroff_vol(usr) = %d\n"
@@ -2022,6 +2091,16 @@ static void rk817_bat_calc_zero_linek(struct rk817_battery_device *battery)
/* xsoc: available rsoc */
xsoc = ocv_soc - dead_soc;
+ battery->zero_dead_voltage = dead_voltage;
+ battery->zero_dead_soc = dead_soc;
+ battery->zero_dead_cap = dead_cap;
+
+ battery->zero_batvol_to_ocv = ocv_voltage;
+ battery->zero_batocv_to_soc = ocv_soc;
+ battery->zero_batocv_to_cap = ocv_cap;
+
+ battery->zero_xsoc = xsoc;
+
DBG("Zero: xsoc = %d\n", xsoc);
/* min_gap_xsoc: reserve xsoc */
if (abs(current_avg) > ZERO_LOAD_LVL1)
@@ -2152,6 +2231,20 @@ static void rk817_bat_zero_algo_prepare(struct rk817_battery_device *battery)
static void rk817_bat_calc_zero_algorithm(struct rk817_battery_device *battery)
{
+ int tmp_soc;
+
+ tmp_soc = battery->zero_dsoc / 1000;
+
+ if (tmp_soc == battery->dsoc / 1000)
+ return;
+
+ if (battery->zero_dsoc > battery->dsoc)
+ return;
+
+ if (battery->zero_dsoc < battery->dsoc - 1000)
+ battery->dsoc -= 1000;
+ else
+ battery->dsoc = battery->zero_dsoc;
}
static void rk817_bat_zero_algorithm(struct rk817_battery_device *battery)
@@ -2160,12 +2253,34 @@ static void rk817_bat_zero_algorithm(struct rk817_battery_device *battery)
battery->zero_timeout_cnt++;
delta_cap = battery->zero_remain_cap - battery->remain_cap;
- delta_soc = battery->zero_linek * (delta_cap / DIV(battery->fcc)) / 10;
-
- DBG("Zero: zero_remain_cap = %d, remain_cap = %d\n",
+ delta_soc = battery->zero_linek * delta_cap / DIV(battery->fcc) / 10;
+
+ DBG("zero algorithm start\n");
+ DBG("DEAD: dead_voltage: %d\n"
+ "dead_soc: %d\n"
+ "dead_cap: %d\n"
+ "powoff_vol: %d\n",
+ battery->zero_dead_voltage,
+ battery->zero_dead_soc,
+ battery->zero_dead_cap,
+ battery->pdata->pwroff_vol);
+ DBG("DEAD: bat_voltage: %d\n"
+ "bat_current: %d\n"
+ "batvol_to_ocv: %d\n"
+ "batocv_to_soc: %d\n"
+ "batocv_to_cap: %d\n",
+ battery->zero_voltage_avg,
+ battery->zero_current_avg,
+ battery->zero_batvol_to_ocv,
+ battery->zero_batocv_to_soc,
+ battery->zero_batocv_to_cap);
+ DBG("DEAD: Xsoc: %d, zero_reserve_dsoc: %d\n",
+ battery->zero_xsoc, battery->pdata->zero_reserve_dsoc);
+ DBG("CAP: zero_remain_cap = %d, remain_cap = %d\n",
battery->zero_remain_cap, battery->remain_cap);
DBG("Zero: zero_delta_cap = %d, zero_link = %d, delta_soc = %d\n",
delta_cap, battery->zero_linek, delta_soc);
+ DBG("zero algorithm end\n");
if ((delta_soc >= MIN_ZERO_DSOC_ACCURACY) ||
(battery->zero_timeout_cnt > MIN_ZERO_OVERCNT) ||
@@ -2174,6 +2289,7 @@ static void rk817_bat_zero_algorithm(struct rk817_battery_device *battery)
battery->zero_timeout_cnt = 0;
battery->zero_dsoc -= delta_soc;
rk817_bat_calc_zero_algorithm(battery);
+ DBG("Zero: dsoc: %d\n", battery->dsoc);
rk817_bat_calc_zero_linek(battery);
}
}
@@ -2315,7 +2431,7 @@ static int rk817_battery_probe(struct platform_device *pdev)
rk817_battery_debug_info(battery);
rk817_bat_update_info(battery);
-
+ rk817_bat_output_info(battery);
battery->bat_monitor_wq = alloc_ordered_workqueue("%s",
WQ_MEM_RECLAIM | WQ_FREEZABLE, "rk817-bat-monitor-wq");
INIT_DELAYED_WORK(&battery->bat_delay_work, rk817_battery_work);