max1720x_battery: validate battery history at boot

add log to log buffer for pixelstats

Bug: 329174074
Test: check result and log is matching
Change-Id: I9417bca255ed357d5ec8d43ba4caa3b6f9f99d91
Signed-off-by: Spade Lee <[email protected]>
diff --git a/max1720x_battery.c b/max1720x_battery.c
index 8db5461..6ee1a7e 100644
--- a/max1720x_battery.c
+++ b/max1720x_battery.c
@@ -1500,6 +1500,67 @@
 
 #define EEPROM_CC_OVERFLOW_BIT	BIT(15)
 #define MAXIM_CYCLE_COUNT_RESET 655
+#define OVERFLOW_START_ENTRY	65
+#define EEPROM_DELTA_CYCLE	10
+#define CYCLE_LSB_UNIT		100 /* LSB: 1% */
+static int max1720x_history_empty(struct max17x0x_eeprom_history *entry)
+{
+	return entry->tempco == 0xffff && entry->rcomp0 == 0xffff;
+}
+
+/* find the first empty entry starting from a position */
+static int max1720x_find_empty(int offset)
+{
+	struct max17x0x_eeprom_history temp = { 0 };
+	int ret, index;
+
+	/* recover (last - OVERFLOW_START_ENTRY + 1) entries */
+	for (index = offset; index < BATT_MAX_HIST_CNT; index++) {
+		ret = gbms_storage_read_data(GBMS_TAG_HIST, &temp,
+					     sizeof(temp), index);
+		if (ret < 0)
+			return -EIO;
+
+		if (max1720x_history_empty(&temp))
+			break;
+	}
+
+	return index == BATT_MAX_HIST_CNT ? -1 : index - offset;
+}
+
+static int max1720x_check_history(struct max1720x_chip *chip)
+{
+	struct max17x0x_eeprom_history temp = { 0 };
+	int ret, misplaced_count, first_empty, est_cycle;
+
+	/* when the entry before the overflow is non empty we are good */
+	ret = gbms_storage_read_data(GBMS_TAG_HIST, &temp, sizeof(temp),
+				     OVERFLOW_START_ENTRY - 1);
+	if (ret < 0 || !max1720x_history_empty(&temp))
+		return ret;
+
+	/* # entries that need to be moved from OVERFLOW_START_ENTRY */
+	misplaced_count = max1720x_find_empty(OVERFLOW_START_ENTRY);
+
+	if (misplaced_count <= 0)
+		return misplaced_count;
+
+	/* where entries will be moved to */
+	first_empty = max1720x_find_empty(0);
+
+	if (first_empty < 0)
+		return -EINVAL;
+
+	est_cycle = (first_empty + misplaced_count) * EEPROM_DELTA_CYCLE;
+
+	gbms_logbuffer_devlog(chip->monitor_log, chip->dev,
+			      LOGLEVEL_INFO, 0, LOGLEVEL_INFO,
+			      "0x4856 %d %d %d %d",
+			      first_empty, misplaced_count, chip->cycle_count, est_cycle);
+
+	return 0;
+}
+
 static int max1720x_restore_battery_cycle(struct max1720x_chip *chip)
 {
 	int ret;
@@ -1550,6 +1611,7 @@
 
 	chip->cycle_reg_ok = true;
 	max1720x_update_cycle_count(chip);
+	max1720x_check_history(chip);
 
 	return 0;
 }