google_eeprom: support for lotr updates
Bug: 203465508
Signed-off-by: AleX Pelosi <[email protected]>
Change-Id: I32e84dd2901131b300d76fd4fb87ec70c68af65d
Signed-off-by: Jack Wu <[email protected]>
diff --git a/gbms_storage.h b/gbms_storage.h
index 7157b16..2c1bd52 100644
--- a/gbms_storage.h
+++ b/gbms_storage.h
@@ -40,9 +40,19 @@
/* Gauge Model State Restore */
#define GBMS_GMSR_LEN 23
+/* TODO: link to the structure used to save this*/
+#define BATT_ONE_HIST_LEN 12
+/* TODO: this depends on the EEPROM size */
+#define BATT_TOTAL_HIST_LEN 924
+/* TODO: this depends on the EEPROM size */
+#define BATT_MAX_HIST_CNT \
+ (BATT_TOTAL_HIST_LEN / BATT_ONE_HIST_LEN) // 77
+
#define GBMS_CCBIN_BUCKET_COUNT 10
+/* Adds BPST and STRD */
+#define GBMS_LOTR_DEFAULT 0xff
#define GBMS_LOTR_V1 1
/*
@@ -55,9 +65,10 @@
GBMS_TAG_BCNT = 0x42434e54,
GBMS_TAG_BGCE = 0x42474345,
GBMS_TAG_BGPN = 0x4247504e,
- GBMS_TAG_BPST = 0x42505354,
+ GBMS_TAG_BPST = 0x42505354, /* LOTRV1: health or spare */
GBMS_TAG_BRES = 0x42524553,
GBMS_TAG_BRID = 0x42524944,
+ GBMS_TAG_CELC = 0x43454C43,
GBMS_TAG_CLHI = 0x424C4849,
GBMS_TAG_CMPC = 0x434d5043,
GBMS_TAG_CNHS = 0x434E4853,
@@ -69,6 +80,8 @@
GBMS_TAG_HIST = 0x48495354,
GBMS_TAG_LOTR = 0x4C4F5452,
GBMS_TAG_MINF = 0x4d494e46,
+ GBMS_TAG_MXSN = 0x4d58534e,
+ GBMS_TAG_MXCN = 0x4d58434e,
/* User Space Read/Write scratch */
GBMS_TAG_RS32 = 0x52533332,
@@ -87,12 +100,10 @@
GBMS_TAG_RAVG = 0x52415647,
GBMS_TAG_RFCN = 0x5246434e,
- GBMS_TAG_SNUM = 0x534e554d,
- GBMS_TAG_MXSN = 0x4d58534e,
- GBMS_TAG_MXCN = 0x4d58434e,
-
GBMS_TAG_SELC = 0x53454C43,
- GBMS_TAG_CELC = 0x43454C43,
+ GBMS_TAG_SNUM = 0x534e554d,
+
+ GBMS_TAG_STRD = 0x53545244, /* LOTRV1: Swelling data */
};
/*
diff --git a/google_eeprom.c b/google_eeprom.c
index cb75ec3..20fec14 100644
--- a/google_eeprom.c
+++ b/google_eeprom.c
@@ -9,21 +9,19 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": %s " fmt, __func__
#include <linux/kernel.h>
+#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/nvmem-consumer.h>
#include <linux/module.h>
#include <linux/delay.h>
#include "gbms_storage.h"
-#define BATT_TOTAL_HIST_LEN 924
-#define BATT_ONE_HIST_LEN 12
-#define BATT_MAX_HIST_CNT \
- (BATT_TOTAL_HIST_LEN / BATT_ONE_HIST_LEN) // 77
-
-#define BATT_EEPROM_TAG_BRID_OFFSET 0x17
-#define BATT_EEPROM_TAG_BRID_LEN 1
#define BATT_EEPROM_TAG_MINF_OFFSET 0x00
#define BATT_EEPROM_TAG_MINF_LEN GBMS_MINF_LEN
+#define BATT_EEPROM_TAG_BGPN_OFFSET 0x03
+#define BATT_EEPROM_TAG_BGPN_LEN GBMS_BGPN_LEN
+#define BATT_EEPROM_TAG_BRID_OFFSET 0x17
+#define BATT_EEPROM_TAG_BRID_LEN 1
#define BATT_EEPROM_TAG_DINF_OFFSET 0x1E
#define BATT_EEPROM_TAG_DINF_LEN GBMS_DINF_LEN
#define BATT_EEPROM_TAG_BCNT_OFFSET 0x2E
@@ -38,10 +36,9 @@
#define BATT_EEPROM_TAG_SELC_LEN 1
#define BATT_EEPROM_TAG_CELC_OFFSET 0x5D
#define BATT_EEPROM_TAG_CELC_LEN 1
+
#define BATT_EEPROM_TAG_HIST_OFFSET 0x5E
#define BATT_EEPROM_TAG_HIST_LEN BATT_ONE_HIST_LEN
-#define BATT_EEPROM_TAG_BGPN_OFFSET 0x03
-#define BATT_EEPROM_TAG_BGPN_LEN GBMS_BGPN_LEN
static struct gbms_storage_desc *gbee_desc;
@@ -303,22 +300,78 @@
.write_data = gbee_storage_write_data,
};
-/* LOTR in a fixed position */
-static int gbms_lotr_update(struct nvmem_device *nvmem, int lotr)
+/* TODO: factor history mechanics out of google battery? */
+static int gbms_hist_move(struct nvmem_device *nvmem, int from, int to, int len)
{
- int ret, lotr_ver = 0;
+ u8 *buff, *p;
+ int index, ret;
+
+ buff = kzalloc(len, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
+
+ /* move only the entries that are used */
+ p = buff;
+ for (index = 0; index < BATT_MAX_HIST_CNT; index++) {
+ ret = nvmem_device_read(nvmem, from, BATT_ONE_HIST_LEN, p);
+ if (ret < 0) {
+ pr_err("%s: cannot read history data (%d)\n", __func__, ret);
+ goto exit;
+ }
+
+ /* verify 1st byte for tempco */
+ if (*p == 0xff)
+ break;
+ /* move to next history entry */
+ from += BATT_ONE_HIST_LEN;
+ p += BATT_ONE_HIST_LEN;
+ }
+
+ ret = nvmem_device_write(nvmem, to, (BATT_ONE_HIST_LEN * index), buff);
+ if (ret < 0)
+ pr_err("%s: cannot write history data (%d)\n", __func__, ret);
+
+exit:
+ kfree(buff);
+ return ret;
+}
+
+/* LOTR is in a fixed position, move */
+static int gbms_lotr_update(struct nvmem_device *nvmem, int lotr_to)
+{
+ int ret, lotr_from = 0;
+ static u8 init_data[5]= { 0 };
ret = nvmem_device_read(nvmem, BATT_EEPROM_TAG_LOTR_OFFSET,
- BATT_EEPROM_TAG_LOTR_LEN, &lotr_ver);
- if (ret < 0 || lotr_ver == lotr)
+ BATT_EEPROM_TAG_LOTR_LEN, &lotr_from);
+ if (ret < 0 || lotr_from == lotr_to)
return ret;
- /* TODO: convert one layout to the other */
- /* eg: zero history when moving from 0xff to 0x01 */
+ if (lotr_to != GBMS_LOTR_V1 || lotr_from != GBMS_LOTR_DEFAULT)
+ return 0;
+
+ ret = gbms_hist_move(nvmem, 0x5E, 0x64, BATT_TOTAL_HIST_LEN);
+ if (ret < 0) {
+ pr_err("%s: cannot move history\n", __func__);
+ return ret;
+ /* TODO: flag this in BPST? */
+ }
+
+ ret = nvmem_device_write(nvmem, 0x5E, sizeof(init_data), init_data);
+ if (ret != sizeof(init_data)) {
+ pr_err("%s: cannot init new fields\n", __func__);
+ return ret < 0 ? ret : -EINVAL;
+ }
+
+ /* TODO: how do we handle backporting? */
/* now write lotr to the right place */
- return nvmem_device_write(nvmem, BATT_EEPROM_TAG_LOTR_OFFSET,
- BATT_EEPROM_TAG_LOTR_LEN, &lotr_ver);
+ ret = nvmem_device_write(nvmem, BATT_EEPROM_TAG_LOTR_OFFSET,
+ BATT_EEPROM_TAG_LOTR_LEN, &lotr_to);
+ if (ret == BATT_EEPROM_TAG_LOTR_LEN)
+ pr_info("%s: lotr migrated %d->%d\n", __func__, lotr_from, lotr_to);
+
+ return ret;
}
static struct gbms_storage_desc *gbms_lotr_2_dsc(int lotr_ver)
diff --git a/google_eeprom_01.c b/google_eeprom_01.c
index a833feb..c96fdf9 100644
--- a/google_eeprom_01.c
+++ b/google_eeprom_01.c
@@ -15,17 +15,18 @@
#include <linux/delay.h>
#include "gbms_storage.h"
-#define BATT_TOTAL_HIST_LEN 924
-#define BATT_ONE_HIST_LEN 12
-#define BATT_MAX_HIST_CNT \
- (BATT_TOTAL_HIST_LEN / BATT_ONE_HIST_LEN) // 77
-
+/* battery health */
#define BATT_EEPROM_TAG_BPST_OFFSET 0x5E
#define BATT_EEPROM_TAG_BPST_LEN 1
+/* swelling data */
+#define BATT_EEPROM_TAG_STRD_OFFSET 0x5F
+#define BATT_EEPROM_TAG_STRD_LEN 4
+
+/* */
#define BATT_EEPROM_TAG_HIST_OFFSET 0x64
#define BATT_EEPROM_TAG_HIST_LEN BATT_ONE_HIST_LEN
-/* add GBMS_TAG_BPST a target specific entry */
+/* Add GBMS_TAG_BPST and GBMS_TAG_STRD move down history */
int gbee_storage01_info(gbms_tag_t tag, size_t *addr, size_t *count, void *ptr)
{
int ret = 0;
@@ -35,6 +36,10 @@
*addr = BATT_EEPROM_TAG_BPST_OFFSET;
*count = BATT_EEPROM_TAG_BPST_LEN;
break;
+ case GBMS_TAG_STRD:
+ *addr = BATT_EEPROM_TAG_STRD_OFFSET;
+ *count = BATT_EEPROM_TAG_STRD_LEN;
+ break;
case GBMS_TAG_HIST:
*addr = BATT_EEPROM_TAG_HIST_OFFSET;
*count = BATT_EEPROM_TAG_HIST_LEN;
@@ -56,7 +61,7 @@
GBMS_TAG_GMSR, GBMS_TAG_BCNT,
GBMS_TAG_CNHS, GBMS_TAG_SELC,
GBMS_TAG_CELC, GBMS_TAG_LOTR,
- GBMS_TAG_BPST };
+ GBMS_TAG_BPST, GBMS_TAG_STRD };
const int max = ARRAY_SIZE(keys);
if (index < 0 || index >= max)