power: pm8921-charger: use SoC % value for charging stop and resume
Current pm8921 charger code doesn't consider the SoC % to determine
end of charging and recharging state. This can cause weird UI display
on SoC % and charging state.
For example, charging is completed when SoC % is not reached 100% or
charging is not completed even if SoC % is already 100%.
So this patch change how to determine end of charging and recharging.
Change-Id: Ice658488744d71117fedb64e0fa0eb7ad34c6573
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 6c0e938..cb569b4 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -148,6 +148,9 @@
int ibat_at_cv_ua;
int soc_at_cv;
int prev_chg_soc;
+ int last_reported_soc;
+ int eoc_check_soc;
+ int soc_adjusted;
};
/*
@@ -1928,6 +1931,43 @@
return 1;
}
+
+static int is_eoc_adjust(struct pm8921_bms_chip *chip, int soc)
+{
+ int batt_state = pm8921_get_batt_state();
+ int ret = 0;
+
+ if (soc != 100)
+ return 0;
+
+ switch (batt_state) {
+ case POWER_SUPPLY_STATUS_CHARGING:
+ if (chip->start_percent != -EINVAL
+ && chip->start_percent != 100)
+ ret = 1;
+ break;
+ case POWER_SUPPLY_STATUS_DISCHARGING:
+ case POWER_SUPPLY_STATUS_NOT_CHARGING:
+ if (chip->soc_adjusted == 1)
+ ret = 1;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int is_recharging(struct pm8921_bms_chip *chip, int soc)
+{
+ if (soc == -EINVAL)
+ return 0;
+ if (pm8921_get_batt_state() == POWER_SUPPLY_STATUS_FULL
+ && soc < 100)
+ return 1;
+ return 0;
+}
+
/*
* Remaining Usable Charge = remaining_charge (charge at ocv instance)
* - coloumb counter charge
@@ -2105,6 +2145,13 @@
soc = calculate_state_of_charge(chip, &raw,
batt_temp, last_chargecycles);
+
+ if (chip->eoc_check_soc
+ && is_recharging(chip, chip->last_reported_soc)) {
+ pm8921_force_start_charging();
+ pr_info("Recharging is started\n");
+ }
+
mutex_unlock(&chip->last_ocv_uv_mutex);
schedule_delayed_work(&chip->calculate_soc_delayed_work,
@@ -2177,10 +2224,18 @@
if (last_soc != -EINVAL && last_soc < soc && soc != 100)
soc = scale_soc_while_chg(chip, delta_time_us, soc, last_soc);
+ if (chip->eoc_check_soc && is_eoc_adjust(chip, soc)) {
+ soc = soc - 1;
+ chip->soc_adjusted = 1;
+ } else {
+ chip->soc_adjusted = 0;
+ }
+
last_soc = soc;
backup_soc_and_iavg(chip, batt_temp, last_soc);
pr_debug("Reported SOC = %d\n", last_soc);
chip->t_soc_queried = now;
+ chip->last_reported_soc = last_soc;
return last_soc;
}
@@ -3224,6 +3279,9 @@
chip->batt_id_channel = pdata->bms_cdata.batt_id_channel;
chip->revision = pm8xxx_get_revision(chip->dev->parent);
chip->enable_fcc_learning = pdata->enable_fcc_learning;
+ chip->last_reported_soc = -EINVAL;
+ chip->eoc_check_soc = pdata->eoc_check_soc;
+ chip->soc_adjusted = 0;
mutex_init(&chip->calib_mutex);
INIT_WORK(&chip->calib_hkadc_work, calibrate_hkadc_work);