google_battery: using different criteria for boundary checking in the bhi algorithm 3/5

Bug: 300357268
Change-Id: I550d67d400b30caa8b3fb87f8f289839661cc975
Signed-off-by: Jenny Ho <hsiufangho@google.com>
diff --git a/google_battery.c b/google_battery.c
index d4e3b63..062d0f6 100644
--- a/google_battery.c
+++ b/google_battery.c
@@ -346,6 +346,7 @@
 	/* set trend points and low boundary */
 	u16 trend[BHI_TREND_POINTS_SIZE];
 	u16 l_bound[BHI_TREND_POINTS_SIZE];
+	int bhi_l_bound_size;
 };
 
 struct health_data
@@ -3652,7 +3653,7 @@
 
 	pr_debug("%s: design=%d reference=%d full_cap_nom=%d full=%d aacr=%d algo=%d\n",
 		 __func__, design_capacity, reference_capacity, full_cap_nom,
-		 full_capacity, aacr_capacity, batt_drv->aacr_algo);
+		 full_capacity, aacr_capacity, aacr_algo);
 
 	return aacr_capacity;
 }
@@ -3842,12 +3843,58 @@
 	return bhi_data->pack_capacity * (100 - bhi_data->capacity_fade) / 100;
 }
 
+static void bhi_l_bound_validity_check(struct batt_drv *batt_drv)
+{
+	struct bhi_data *bhi_data = &batt_drv->health_data.bhi_data;
+	int cnt;
+
+	for (cnt = 0; cnt < BHI_TREND_POINTS_SIZE; cnt ++)
+		if (bhi_data->l_bound[cnt] == 0)
+			break;
+
+	bhi_data->bhi_l_bound_size = cnt;
+
+	/* data validity */
+	for (cnt = 0; cnt < bhi_data->bhi_l_bound_size; cnt++) {
+		if (batt_drv->battery_capacity &&
+		    bhi_data->l_bound[cnt] > batt_drv->battery_capacity) {
+			bhi_data->bhi_l_bound_size = 0;
+			break;
+		}
+	}
+}
+
+static int bhi_get_l_bound(int cc, const struct batt_drv *batt_drv)
+{
+	const struct bhi_data *bhi_data = &batt_drv->health_data.bhi_data;
+	const u16 *l_bound = bhi_data->l_bound;
+	const int max_size = bhi_data->bhi_l_bound_size - 1;
+	int index, ca_upper, ca_under;
+
+	/* no available data */
+	if (max_size <= 0)
+		return 0;
+
+	if (cc <= 100)
+		return l_bound[0];
+
+	index = cc / 100;
+
+	if (index >= max_size)
+		index = max_size;
+
+	ca_upper = l_bound[index];
+	ca_under = l_bound[index - 1];
+
+	return ca_under + (cc - (index * 100)) * (ca_upper - ca_under) / 100;
+}
+
 /* The limit for capacity is 80% of design */
 static int bhi_calc_cap_index(int algo, struct batt_drv *batt_drv)
 {
 	const struct health_data *health_data = &batt_drv->health_data;
 	const struct bhi_data *bhi_data = &health_data->bhi_data;
-	int capacity_health, index, capacity_aacr = 0;
+	int capacity_health, index, capacity_bound = 0;
 
 	if (algo == BHI_ALGO_DISABLED)
 		return BHI_ALGO_FULL_HEALTH;
@@ -3865,11 +3912,21 @@
 		const int cycle_count = batt_drv->fake_aacr_cc ?
 					batt_drv->fake_aacr_cc : batt_drv->cycle_count;
 
-		capacity_aacr =  aacr_get_capacity_for_algo(batt_drv, cycle_count,
-							   batt_drv->aacr_algo);
-
-		if (capacity_health < capacity_aacr)
-			capacity_health = capacity_aacr;
+		capacity_bound = bhi_get_l_bound(cycle_count, batt_drv);
+		if (capacity_bound) {
+			if (capacity_health < capacity_bound)
+				capacity_health = capacity_bound;
+		} else if (algo == BHI_ALGO_ACHI_RAVG_B) {
+			capacity_bound = aacr_get_capacity_for_algo(batt_drv, cycle_count,
+								    BATT_AACR_ALGO_LOW_B);
+			if (capacity_health > capacity_bound)
+				capacity_health = capacity_bound;
+		} else {
+			capacity_bound = aacr_get_capacity_for_algo(batt_drv, cycle_count,
+								    BATT_AACR_ALGO_DEFAULT);
+			if (capacity_health < capacity_bound)
+				capacity_health = capacity_bound;
+		}
 	}
 
 	/*
@@ -3879,8 +3936,8 @@
 
 	index = (capacity_health * BHI_ALGO_FULL_HEALTH) / bhi_data->pack_capacity;
 
-	pr_debug("%s: algo=%d index=%d ch=%d, ca=%d, pc=%d, fr=%d\n", __func__,
-		algo, index, capacity_health, capacity_aacr, bhi_data->pack_capacity,
+	pr_debug("%s: algo=%d index=%d ch=%d, cb=%d, pc=%d, fr=%d\n", __func__,
+		algo, index, capacity_health, capacity_bound, bhi_data->pack_capacity,
 		bhi_data->capacity_fade);
 
 	return index;
@@ -7561,6 +7618,8 @@
 
 		if ((int)batt_id == batt_drv->batt_id) {
 			memcpy(&bhi_data->l_bound, l_bound, sizeof(l_bound));
+			bhi_l_bound_validity_check(batt_drv);
+
 			break;
 		}
 
@@ -9666,6 +9725,7 @@
 static int batt_bhi_init(struct batt_drv *batt_drv)
 {
 	struct health_data *health_data = &batt_drv->health_data;
+	struct bhi_data *bhi_data = &health_data->bhi_data;
 	int ret;
 
 	/* see enum bhi_algo */
@@ -9725,6 +9785,17 @@
 	/* need battery id to get right trend points */
 	batt_drv->batt_id = GPSY_GET_PROP(batt_drv->fg_psy, GBMS_PROP_BATT_ID);
 
+	ret = of_property_read_u16_array(batt_id_node(batt_drv),
+					 "google,bhi-l-bound", &bhi_data->l_bound[0],
+					 BHI_TREND_POINTS_SIZE);
+	if (ret == 0) {
+		bhi_l_bound_validity_check(batt_drv);
+		pr_info("bhi_l_bound [%d, %d, %d, %d, %d, %d, %d, %d], size:%d\n",
+			bhi_data->l_bound[0], bhi_data->l_bound[1], bhi_data->l_bound[2],
+			bhi_data->l_bound[3], bhi_data->l_bound[4], bhi_data->l_bound[5],
+			bhi_data->l_bound[6], bhi_data->l_bound[7], bhi_data->bhi_l_bound_size);
+	}
+
 	/* debug data initialization */
 	health_data->bhi_debug_cycle_count = 0;
 	health_data->bhi_debug_cap_index = 0;