qpnp-fg-gen3: prime CC_SOC_SW when capacity learning begins
CC_SOC_SW can accumulate error over time and get saturated high during capacity learning. Prime it to a value based on battery SOC when capacity learning begins. This way, it can be ensured that CC_SOC_SW doesn't saturate in a capacity learning cycle. Change-Id: I2866ed6dadee84e84bf28fb08dc3a5a0ae353852 Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
This commit is contained in:
parent
e0e09f7190
commit
b3dd099154
1 changed files with 28 additions and 21 deletions
|
@ -525,7 +525,7 @@ static int fg_get_sram_prop(struct fg_chip *chip, enum fg_sram_param_id id,
|
|||
}
|
||||
|
||||
#define CC_SOC_30BIT GENMASK(29, 0)
|
||||
static int fg_get_cc_soc(struct fg_chip *chip, int *val)
|
||||
static int fg_get_charge_raw(struct fg_chip *chip, int *val)
|
||||
{
|
||||
int rc, cc_soc;
|
||||
|
||||
|
@ -539,7 +539,7 @@ static int fg_get_cc_soc(struct fg_chip *chip, int *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fg_get_cc_soc_sw(struct fg_chip *chip, int *val)
|
||||
static int fg_get_charge_counter(struct fg_chip *chip, int *val)
|
||||
{
|
||||
int rc, cc_soc;
|
||||
|
||||
|
@ -1241,7 +1241,7 @@ static void fg_cap_learning_post_process(struct fg_chip *chip)
|
|||
chip->cl.final_cc_uah, old_cap, chip->cl.learned_cc_uah);
|
||||
}
|
||||
|
||||
static int fg_cap_learning_process_full_data(struct fg_chip *chip)
|
||||
static int fg_cap_learning_process_full_data(struct fg_chip *chip)
|
||||
{
|
||||
int rc, cc_soc_sw, cc_soc_delta_pct;
|
||||
int64_t delta_cc_uah;
|
||||
|
@ -1263,30 +1263,39 @@ static int fg_cap_learning_process_full_data(struct fg_chip *chip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fg_cap_learning_begin(struct fg_chip *chip, int batt_soc)
|
||||
#define BATT_SOC_32BIT GENMASK(31, 0)
|
||||
static int fg_cap_learning_begin(struct fg_chip *chip, u32 batt_soc)
|
||||
{
|
||||
int rc, cc_soc_sw;
|
||||
int rc, cc_soc_sw, batt_soc_msb;
|
||||
|
||||
if (DIV_ROUND_CLOSEST(batt_soc * 100, FULL_SOC_RAW) >
|
||||
batt_soc_msb = batt_soc >> 24;
|
||||
if (DIV_ROUND_CLOSEST(batt_soc_msb * 100, FULL_SOC_RAW) >
|
||||
chip->dt.cl_start_soc) {
|
||||
fg_dbg(chip, FG_CAP_LEARN, "Battery SOC %d is high!, not starting\n",
|
||||
batt_soc);
|
||||
batt_soc_msb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
chip->cl.init_cc_uah = div64_s64(chip->cl.learned_cc_uah * batt_soc,
|
||||
chip->cl.init_cc_uah = div64_s64(chip->cl.learned_cc_uah * batt_soc_msb,
|
||||
FULL_SOC_RAW);
|
||||
rc = fg_get_sram_prop(chip, FG_SRAM_CC_SOC_SW, &cc_soc_sw);
|
||||
|
||||
/* Prime cc_soc_sw with battery SOC when capacity learning begins */
|
||||
cc_soc_sw = div64_s64((int64_t)batt_soc * CC_SOC_30BIT,
|
||||
BATT_SOC_32BIT);
|
||||
rc = fg_sram_write(chip, chip->sp[FG_SRAM_CC_SOC_SW].addr_word,
|
||||
chip->sp[FG_SRAM_CC_SOC_SW].addr_byte, (u8 *)&cc_soc_sw,
|
||||
chip->sp[FG_SRAM_CC_SOC_SW].len, FG_IMA_ATOMIC);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in getting CC_SOC_SW, rc=%d\n", rc);
|
||||
return rc;
|
||||
pr_err("Error in writing cc_soc_sw, rc=%d\n", rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
chip->cl.init_cc_soc_sw = cc_soc_sw;
|
||||
chip->cl.active = true;
|
||||
fg_dbg(chip, FG_CAP_LEARN, "Capacity learning started @ battery SOC %d init_cc_soc_sw:%d\n",
|
||||
batt_soc, chip->cl.init_cc_soc_sw);
|
||||
return 0;
|
||||
batt_soc_msb, chip->cl.init_cc_soc_sw);
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int fg_cap_learning_done(struct fg_chip *chip)
|
||||
|
@ -1318,7 +1327,7 @@ out:
|
|||
#define FULL_SOC_RAW 255
|
||||
static void fg_cap_learning_update(struct fg_chip *chip)
|
||||
{
|
||||
int rc, batt_soc;
|
||||
int rc, batt_soc, batt_soc_msb;
|
||||
|
||||
mutex_lock(&chip->cl.lock);
|
||||
|
||||
|
@ -1337,11 +1346,9 @@ static void fg_cap_learning_update(struct fg_chip *chip)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* We need only the most significant byte here */
|
||||
batt_soc = (u32)batt_soc >> 24;
|
||||
|
||||
batt_soc_msb = (u32)batt_soc >> 24;
|
||||
fg_dbg(chip, FG_CAP_LEARN, "Chg_status: %d cl_active: %d batt_soc: %d\n",
|
||||
chip->charge_status, chip->cl.active, batt_soc);
|
||||
chip->charge_status, chip->cl.active, batt_soc_msb);
|
||||
|
||||
/* Initialize the starting point of learning capacity */
|
||||
if (!chip->cl.active) {
|
||||
|
@ -1363,7 +1370,7 @@ static void fg_cap_learning_update(struct fg_chip *chip)
|
|||
|
||||
if (chip->charge_status == POWER_SUPPLY_STATUS_NOT_CHARGING) {
|
||||
fg_dbg(chip, FG_CAP_LEARN, "Capacity learning aborted @ battery SOC %d\n",
|
||||
batt_soc);
|
||||
batt_soc_msb);
|
||||
chip->cl.active = false;
|
||||
chip->cl.init_cc_uah = 0;
|
||||
}
|
||||
|
@ -2821,7 +2828,7 @@ static int fg_psy_get_property(struct power_supply *psy,
|
|||
pval->intval = chip->cyc_ctr.id;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_NOW_RAW:
|
||||
rc = fg_get_cc_soc(chip, &pval->intval);
|
||||
rc = fg_get_charge_raw(chip, &pval->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_NOW:
|
||||
pval->intval = chip->cl.init_cc_uah;
|
||||
|
@ -2830,7 +2837,7 @@ static int fg_psy_get_property(struct power_supply *psy,
|
|||
pval->intval = chip->cl.learned_cc_uah;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
|
||||
rc = fg_get_cc_soc_sw(chip, &pval->intval);
|
||||
rc = fg_get_charge_counter(chip, &pval->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
|
||||
rc = fg_get_time_to_full(chip, &pval->intval);
|
||||
|
|
Loading…
Add table
Reference in a new issue