qpnp-fg-gen3: clear profile integrity bit upon battery removal

In certain cases like battery hotswap where a strong charger is
connected and battery is re-inserted, the expectation from the
user is to reload the battery profile. This cannot happen unless
a dVdd reset happens and wipes out FG SRAM. To help with the
aforementioned scenario, clear the profile integrity bit every
time when the battery is re-inserted. This way, FG driver will
reload the profile everytime upon battery insertion.

When the battery is missing, cycle counters cannot be cleared as
the access to FG SRAM might not succeed. Hence remove it from the
battery removal path. It will be cleared anyways when the profile
is loaded after the battery is inserted.

While at it, show the cached value of battery_id instead of
reading it every time from RR_ADC peripheral. When the battery is
re-inserted, battery id is obtained from RR_ADC driver anyways
which is sufficient.

Change-Id: I0b9566f7a9fcc81e26e68280382e2d960c49eeb5
Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
This commit is contained in:
Subbaraman Narayanamurthy 2016-12-22 15:09:38 -08:00
parent 1897bd682b
commit 3d493610e3

View file

@ -1898,6 +1898,17 @@ static bool is_profile_load_required(struct fg_chip *chip)
return true;
}
static void clear_battery_profile(struct fg_chip *chip)
{
u8 val = 0;
int rc;
rc = fg_sram_write(chip, PROFILE_INTEGRITY_WORD,
PROFILE_INTEGRITY_OFFSET, &val, 1, FG_IMA_DEFAULT);
if (rc < 0)
pr_err("failed to write profile integrity rc=%d\n", rc);
}
#define SOC_READY_WAIT_MS 2000
static int __fg_restart(struct fg_chip *chip)
{
@ -2413,7 +2424,7 @@ static int fg_psy_get_property(struct power_supply *psy,
pval->intval = chip->cl.nom_cap_uah;
break;
case POWER_SUPPLY_PROP_RESISTANCE_ID:
rc = fg_get_batt_id(chip, &pval->intval);
pval->intval = chip->batt_id_ohms;
break;
case POWER_SUPPLY_PROP_BATTERY_TYPE:
pval->strval = fg_get_battery_type(chip);
@ -2835,7 +2846,6 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *data)
if (chip->battery_missing) {
chip->profile_available = false;
chip->profile_loaded = false;
clear_cycle_counter(chip);
chip->soc_reporting_ready = false;
} else {
rc = fg_get_batt_profile(chip);
@ -2844,6 +2854,7 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *data)
pr_err("Error in getting battery profile, rc:%d\n", rc);
return IRQ_HANDLED;
}
clear_battery_profile(chip);
schedule_delayed_work(&chip->profile_load_work, 0);
}