summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavide Garberi <dade.garberi@gmail.com>2019-04-20 18:50:43 +0200
committerDavide Garberi <dade.garberi@gmail.com>2022-07-27 19:23:19 +0200
commit53cd7a12c2f36078bdcdfaa038e47db8956f959d (patch)
tree66a50b2c36d943f1af9406af6dd43e7b950ec22f
parent505c3a88400e48761979205b7aff769aae82d1db (diff)
power: qpnp-fg: Implement SUPPORT_SOC_SHOW_OPTIMIZATION
* Without this the battery is sometimes being reported as charged when it is at 98% or 99% Change-Id: I81e70d1a044c642716b3a920b49f8583c083d4a5
-rw-r--r--drivers/power/supply/qcom/qpnp-fg.c74
1 files changed, 71 insertions, 3 deletions
diff --git a/drivers/power/supply/qcom/qpnp-fg.c b/drivers/power/supply/qcom/qpnp-fg.c
index 68ea0ce69986..2f5b9e47aba2 100644
--- a/drivers/power/supply/qcom/qpnp-fg.c
+++ b/drivers/power/supply/qcom/qpnp-fg.c
@@ -651,6 +651,8 @@ struct fg_chip {
bool batt_info_restore;
bool *batt_range_ocv;
int *batt_range_pct;
+ ktime_t soc_kt;
+ u8 is_op_soc;
};
/* FG_MEMIF DEBUGFS structures */
@@ -2238,6 +2240,74 @@ static int get_monotonic_soc_raw(struct fg_chip *chip)
#define MISSING_CAPACITY 100
#define FULL_CAPACITY 100
#define FULL_SOC_RAW 0xFF
+
+static int bound_soc(int soc)
+{
+ soc = max(0, soc);
+ soc = min(100, soc);
+ return soc;
+}
+
+#define LENUK_OP_FIR_SOC 60
+#define LENUK_OP_SEC_SOC 85
+#define LENUK_SOC_CHANGE_MS 25000
+static int set_soc_remap_point(struct fg_chip *chip, int soc)
+{
+ int mapped_soc = 0;
+ if (!chip->is_op_soc) {
+ chip->soc_kt = ktime_get_boottime();
+ mapped_soc = soc;
+ chip->is_op_soc = 1;
+ } else {
+ ktime_t now_kt, delta_kt;
+ int delta_ms;
+ now_kt = ktime_get_boottime();
+ delta_kt = ktime_sub(now_kt, chip->soc_kt);
+ delta_ms = (int)div64_s64(ktime_to_ns(delta_kt), 1000000);
+ if (delta_ms <= LENUK_SOC_CHANGE_MS) {
+ if (chip->status == POWER_SUPPLY_STATUS_CHARGING)
+ mapped_soc = soc;
+ else
+ mapped_soc = soc + 1;
+ }else {
+ if (chip->status == POWER_SUPPLY_STATUS_CHARGING)
+ mapped_soc = soc + 1;
+ else
+ mapped_soc = soc;
+ }
+ }
+ return mapped_soc;
+}
+
+static int soc_remap_process(struct fg_chip *chip, int soc)
+{
+ int maped_soc = 0;
+ switch(soc){
+ case LENUK_OP_FIR_SOC :
+ maped_soc = set_soc_remap_point(chip,soc);
+ break;
+ case LENUK_OP_SEC_SOC :
+ maped_soc = set_soc_remap_point(chip,soc) + 1;
+ break;
+ default:
+ chip->is_op_soc = 0;
+ if(soc >= 61 && soc <= 84 )
+ maped_soc = soc + 1;
+ else if(soc >= 86 && soc <= 100)
+ maped_soc = bound_soc(soc + 2);
+ else
+ maped_soc = soc;
+ }
+ pr_info("pre_map_soc is %d,post_map_soc is %d\n",soc,maped_soc);
+ return maped_soc;
+}
+static int soc_show_op(struct fg_chip *chip, int msoc)
+{
+ int soc = DIV_ROUND_CLOSEST((msoc - 1) * (FULL_CAPACITY - 2),
+ FULL_SOC_RAW - 2) + 1;
+ return soc_remap_process(chip, soc);
+}
+
static int get_prop_capacity(struct fg_chip *chip)
{
int msoc, rc;
@@ -2285,9 +2355,7 @@ static int get_prop_capacity(struct fg_chip *chip)
} else if (msoc == FULL_SOC_RAW) {
return FULL_CAPACITY;
}
-
- return DIV_ROUND_CLOSEST((msoc - 1) * (FULL_CAPACITY - 2),
- FULL_SOC_RAW - 2) + 1;
+ return soc_show_op(chip, msoc);
}
#define HIGH_BIAS 3