power: pm8921-bms: fix issues with reading 0 for OCV
There are cases when the OCV value in the register is 0. Most likely
the pmic did not go through a PON sequence or it was disabled while
PON happened.
There are couple of issues with reading 0 in the OCV register
- The driver jumps to end of charge condition when the register read is 0.
- The driver assumes that it never took an OCV and behaves as if it is
reading the PON OCV on every calculation. Since it sees a value of 0,
it estimates OCV on every calculation.
Fix this case by initializing ocv_reading_at_100 and
prev_last_good_ocv_raw to an impossibly high value to differentiate
it from the 0 OCV case.
Change-Id: I1560e0df1c89be1db1e1d1aeaaeef2e6da5f85c1
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index 38c6056..ed57f2c 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -730,8 +730,9 @@
* CC_RESOLUTION_N, CC_RESOLUTION_D, CC_READING_TICKS
* and rsense
*/
-#define CC_RAW_5MAH 0x00110000
-#define MIN_OCV_UV 2000000
+#define CC_RAW_5MAH 0x00110000
+#define MIN_OCV_UV 2000000
+#define OCV_RAW_UNINITIALIZED 0xFFFF
static int read_soc_params_raw(struct pm8921_bms_chip *chip,
struct pm8921_soc_params *raw,
int batt_temp_decidegc)
@@ -751,7 +752,7 @@
usb_chg = usb_chg_plugged_in(chip);
- if (chip->prev_last_good_ocv_raw == 0) {
+ if (chip->prev_last_good_ocv_raw == OCV_RAW_UNINITIALIZED) {
chip->prev_last_good_ocv_raw = raw->last_good_ocv_raw;
convert_vbatt_raw_to_uv(chip, usb_chg,
@@ -803,7 +804,7 @@
/* fake a high OCV if we are just done charging */
if (chip->ocv_reading_at_100 != raw->last_good_ocv_raw) {
- chip->ocv_reading_at_100 = 0;
+ chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
chip->cc_reading_at_100 = 0;
} else {
/*
@@ -3013,6 +3014,8 @@
chip->start_percent = -EINVAL;
chip->end_percent = -EINVAL;
chip->last_cc_uah = INT_MIN;
+ chip->ocv_reading_at_100 = OCV_RAW_UNINITIALIZED;
+ chip->prev_last_good_ocv_raw = OCV_RAW_UNINITIALIZED;
chip->shutdown_soc_valid_limit = pdata->shutdown_soc_valid_limit;
chip->adjust_soc_low_threshold = pdata->adjust_soc_low_threshold;