Merge cherrypicks of ['partner-android-review.googlesource.com/3020167', 'partner-android-review.googlesource.com/3036702', 'partner-android-review.googlesource.com/3036782', 'partner-android-review.googlesource.com/3038036', 'partner-android-review.googlesource.com/3043516'] into sparse-12859539-L51200030008761432.
SPARSE_CHANGE: Ic3c98a1728fb68c1a8da8ab44646b426b9e67062
SPARSE_CHANGE: Ief29811aba1d50eb21fc3de584cd6c38f0f9e133
SPARSE_CHANGE: I6e0238f0a4bc666c0143c69c7d3b19add7cef85c
SPARSE_CHANGE: Iaa51de3c538d21d5eb1b7f5ae139ccc57e2871cb
SPARSE_CHANGE: I6ee215c6bbc602c3aebb496f966fb1845b7da6bf
Change-Id: I84e307d9decbe9768c41b954604391044378268f
Signed-off-by: Coastguard Worker <[email protected]>
diff --git a/gbms_power_supply.h b/gbms_power_supply.h
index 05ca729..6ef82e2 100644
--- a/gbms_power_supply.h
+++ b/gbms_power_supply.h
@@ -96,6 +96,7 @@
GBMS_PROP_BATT_ID, /* GBMS battery id */
GBMS_PROP_RECAL_FG, /* GBMS FG reset */
GBMS_PROP_LOGBUFFER_BD, /* GBMS pass logbuffer_bd address */
+ GBMS_PROP_AAFV, /* GBMS pass aafv to FG */
};
union gbms_propval {
diff --git a/google_battery.c b/google_battery.c
index 05a41bd..7529071 100644
--- a/google_battery.c
+++ b/google_battery.c
@@ -287,6 +287,13 @@
BATT_AAFV_MAX,
};
+enum batt_aact_state {
+ BATT_AACT_UNKNOWN = -1,
+ BATT_AACT_DISABLED = 0,
+ BATT_AACT_ENABLED = 1,
+ BATT_AACT_MAX,
+};
+
#define BATT_TEMP_RECORD_THR 3
/* discharge saved after charge */
#define SD_CHG_START 0
@@ -526,6 +533,7 @@
/* for testing */
int fake_aacr_cc;
int fake_aafv_cc;
+ int fake_aact_cc;
/* props */
int soh;
@@ -650,6 +658,16 @@
struct logbuffer *bd_log;
struct mutex aafv_state_lock;
+ /* AACT: Aged Adjusted Charge Table */
+ enum batt_aact_state aact_state;
+ struct mutex aact_state_lock;
+
+ /* AACP: Configuration Version for AAFV, AACR and AACT for the device */
+ int aacp_version;
+
+ /* AACC: Age adjusted cycle count */
+ int aacc;
+
/* BHI: updated on disconnect, EOC */
struct health_data health_data;
struct swelling_data sd;
@@ -1959,6 +1977,10 @@
ce_data->csi_aggregate_status = batt_drv->csi_stats.aggregate_status;
ce_data->csi_aggregate_type = batt_drv->csi_stats.aggregate_type;
+ /* Log aacp_version and aacc into chg_stats */
+ ce_data->aacp_version = batt_drv->aacp_version;
+ ce_data->aacc = batt_drv->aacc;
+
/* Note: To log new voltage tiers, add to list in go/pixel-vtier-defs */
/* --- Log tiers in PARALLEL below --- */
@@ -2362,7 +2384,7 @@
ce_data->adapter_details.ad_voltage * 100,
ce_data->adapter_details.ad_amperage * 100);
- len += scnprintf(&buff[len], size - len, "%s%hu,%hu, %hu,%hu %d %hu,%hu",
+ len += scnprintf(&buff[len], size - len, "%s%hu,%hu, %hu,%hu %d %hu,%hu, %d,%d",
(verbose) ? "\nS: " : ", ",
ce_data->charging_stats.ssoc_in,
ce_data->charging_stats.voltage_in,
@@ -2370,7 +2392,9 @@
ce_data->charging_stats.voltage_out,
state_capacity,
ce_data->csi_aggregate_status,
- ce_data->csi_aggregate_type);
+ ce_data->csi_aggregate_type,
+ ce_data->aacp_version,
+ ce_data->aacc);
if (verbose) {
@@ -3950,7 +3974,7 @@
if (batt_drv->fake_aacr_cc)
cycle_count = batt_drv->fake_aacr_cc;
else
- cycle_count = batt_drv->cycle_count;
+ cycle_count = batt_drv->aacc;
if (batt_drv->aacr_state == BATT_AACR_DISABLED)
goto exit_done;
@@ -4259,7 +4283,7 @@
if (bhi_algo_has_bounds(algo)) {
const int cycle_count = batt_drv->fake_aacr_cc ?
- batt_drv->fake_aacr_cc : batt_drv->cycle_count;
+ batt_drv->fake_aacr_cc : batt_drv->aacc;
capacity_health = bhi_algo_apply_bounds(algo, capacity_health, cycle_count,
bhi_data);
@@ -4855,7 +4879,7 @@
static u32 aafv_update_state(struct batt_drv *batt_drv)
{
- int cycle_count = batt_drv->cycle_count;
+ int cycle_count = batt_drv->aacc;
int offset, aafv_offset = 0;
mutex_lock(&batt_drv->aafv_state_lock);
@@ -4902,6 +4926,16 @@
*fv_uv = (int)aafv_fv;
}
+/* AACC ------------------------------------------------------------------- */
+
+static void aacc_update_cycle_count(struct batt_drv *batt_drv)
+{
+ int cycle_count = batt_drv->cycle_count;
+
+ /* TODO: AACC is TBD */
+ batt_drv->aacc = cycle_count;
+}
+
/* ------------------------------------------------------------------------ */
/* TODO: factor msc_logic_irdop from the logic about tier switch */
@@ -5194,8 +5228,14 @@
if (vbatt_idx != batt_drv->vbatt_idx || temp_idx != batt_drv->temp_idx) {
const int last_vbatt_idx = gbms_msc_get_last_voltage_idx(profile, temp_idx);
- if (vbatt_idx == last_vbatt_idx)
+ if (vbatt_idx == last_vbatt_idx) {
+ int ret;
+
aafv_update_voltage(batt_drv, &fv_uv, last_vbatt_idx);
+ ret = GPSY_SET_PROP(fg_psy, GBMS_PROP_AAFV, fv_uv);
+ if (ret < 0)
+ pr_err("pass aafv to FG failed %d", ret);
+ }
}
batt_prlog(batt_prlog_level(changed),
@@ -5287,16 +5327,18 @@
{
u32 capacity = aacr_get_capacity(batt_drv);
- if (capacity != batt_drv->chg_profile.capacity_ma) {
- gbms_logbuffer_devlog(batt_drv->ttf_stats.ttf_log, batt_drv->device,
- LOGLEVEL_INFO, 0, LOGLEVEL_INFO, "AACR: capacity:%d->%d, state:%d, "
- "algo:%d, cycle_grace:%d, cycle_max:%d, min_cap_rate:%d, cliff_cap_rate:%d",
- batt_drv->chg_profile.capacity_ma, capacity, batt_drv->aacr_state,
- batt_drv->aacr_algo, batt_drv->aacr_cycle_grace, batt_drv->aacr_cycle_max,
- batt_drv->aacr_min_capacity_rate, batt_drv->aacr_cliff_capacity_rate);
- gbms_init_chg_table(&batt_drv->chg_profile, batt_drv->device->of_node, capacity);
- google_battery_dump_profile(&batt_drv->chg_profile);
- }
+ if (capacity == batt_drv->chg_profile.capacity_ma)
+ return;
+
+ gbms_logbuffer_devlog(batt_drv->ttf_stats.ttf_log, batt_drv->device,
+ LOGLEVEL_INFO, 0, LOGLEVEL_INFO,
+ "AACR: capacity:%d->%d, state:%d, algo:%d, cycle_grace:%d, cycle_max:%d, min_cap_rate:%d, cliff_cap_rate:%d",
+ batt_drv->chg_profile.capacity_ma, capacity, batt_drv->aacr_state,
+ batt_drv->aacr_algo, batt_drv->aacr_cycle_grace,
+ batt_drv->aacr_cycle_max, batt_drv->aacr_min_capacity_rate,
+ batt_drv->aacr_cliff_capacity_rate);
+ gbms_init_chg_table(&batt_drv->chg_profile, batt_drv->device->of_node, capacity);
+ google_battery_dump_profile(&batt_drv->chg_profile);
}
/* cell fault: disconnect of one of the battery cells */
@@ -5397,6 +5439,60 @@
return 0;
}
+/* AACT ------------------------------------------------------------------- */
+
+/* call holding mutex_lock(&batt_drv->aact_state_lock); */
+static void aact_reset(struct gbms_chg_profile *profile)
+{
+ profile->aact_nb_limits = 0;
+ profile->aact_idx = 0;
+}
+
+/* call holding mutex_lock(&batt_drv->aact_state_lock); */
+static int aact_get_index(const struct batt_drv *batt_drv)
+{
+ int cycle_count = batt_drv->aacc;
+
+ if (batt_drv->fake_aact_cc)
+ cycle_count = batt_drv->fake_aact_cc;
+
+ return gbms_aact_get_index(&batt_drv->chg_profile, cycle_count);
+}
+
+/* call holding mutex_lock(&batt_drv->aact_state_lock); */
+static int aact_update_chg_table(struct batt_drv *batt_drv)
+{
+ struct gbms_chg_profile *profile = &batt_drv->chg_profile;
+ struct device_node *node = batt_drv->device->of_node;
+ int ret;
+
+ if (!profile->aact_init_profile && batt_drv->aact_state == BATT_AACT_ENABLED) {
+ /* init AACT charge table */
+ ret = gbms_init_aact_profile(profile, node);
+ if (ret < 0)
+ return ret;
+
+ gbms_init_chg_table(profile, node, batt_drv->battery_capacity);
+ } else if (profile->aact_init_profile && batt_drv->aact_state == BATT_AACT_DISABLED) {
+ /* reset AACT */
+ aact_reset(profile);
+
+ /* init default charge table */
+ ret = gbms_init_chg_profile(profile, node);
+ if (ret < 0)
+ return ret;
+
+ gbms_init_chg_table(profile, node, batt_drv->battery_capacity);
+ }
+
+ if (batt_drv->aact_state == BATT_AACT_ENABLED)
+ profile->aact_idx = aact_get_index(batt_drv);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
/* call holding mutex_lock(&batt_drv->chg_lock); */
static int batt_chg_logic(struct batt_drv *batt_drv)
{
@@ -5447,6 +5543,9 @@
batt_update_cycle_count(batt_drv);
batt_rl_reset(batt_drv);
+ /* aacc: cycle count */
+ aacc_update_cycle_count(batt_drv);
+
/* charging_policy: vote AC false when disconnected */
gvotable_cast_long_vote(batt_drv->charging_policy_votable, "MSC_AC",
CHARGING_POLICY_VOTE_ADAPTIVE_AC, false);
@@ -5492,6 +5591,26 @@
if (bhi_data->res_state.estimate_filter)
batt_res_state_set(&bhi_data->res_state, true);
+ mutex_lock(&batt_drv->aact_state_lock);
+ err = aact_update_chg_table(batt_drv);
+ if (err < 0) {
+ struct gbms_chg_profile *profile = &batt_drv->chg_profile;
+ struct device_node *node = batt_drv->device->of_node;
+ int rc;
+
+ /* reset AACT */
+ aact_reset(profile);
+
+ /* set state to unknown and init default charge table */
+ batt_drv->aact_state = BATT_AACT_UNKNOWN;
+ rc = gbms_init_chg_profile(profile, node);
+ if (rc == 0)
+ gbms_init_chg_table(profile, node, aacr_get_capacity(batt_drv));
+
+ pr_err("Cannot update aact charge table (%d)\n", err);
+ }
+ mutex_unlock(&batt_drv->aact_state_lock);
+
aacr_update_chg_table(batt_drv);
batt_chg_stats_start(batt_drv);
@@ -6264,6 +6383,7 @@
if (!tmp)
return -ENOMEM;
+ mutex_lock(&batt_drv->aact_state_lock);
if (raw_profile_cycles) {
struct gbms_chg_profile profile;
int count;
@@ -6272,6 +6392,14 @@
if (len < 0)
goto exit_done;
+ if (batt_drv->aact_state == BATT_AACT_ENABLED) {
+ len = gbms_init_aact_profile(&profile, batt_drv->device->of_node);
+ if (len < 0)
+ goto exit_done;
+
+ profile.aact_idx = aact_get_index(batt_drv);
+ }
+
/* len is the capacity */
len = aacr_get_capacity_at_cycle(batt_drv, raw_profile_cycles);
if (len <= 0) {
@@ -6291,6 +6419,7 @@
len = simple_read_from_buffer(buf, count, ppos, tmp, strlen(tmp));
exit_done:
+ mutex_unlock(&batt_drv->aact_state_lock);
kfree(tmp);
return len;
}
@@ -8201,6 +8330,112 @@
static const DEVICE_ATTR_RO(aafv_offset);
+/* AACT ------------------------------------------------------------------- */
+
+static ssize_t aact_state_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct power_supply *psy = container_of(dev, struct power_supply, dev);
+ struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+ int val, ret = 0;
+
+ ret = kstrtoint(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&batt_drv->aact_state_lock);
+
+ if (batt_drv->aact_state == val)
+ goto done;
+
+ if (val == BATT_AACT_ENABLED && batt_drv->aact_state != BATT_AACT_DISABLED) {
+ mutex_unlock(&batt_drv->aact_state_lock);
+ return -EINVAL;
+ }
+
+ dev_info(batt_drv->device, "AACT: aact_state: %d -> %d\n", batt_drv->aact_state, val);
+ batt_drv->aact_state = val;
+
+ ret = aact_update_chg_table(batt_drv);
+ if (ret < 0) {
+ struct gbms_chg_profile *profile = &batt_drv->chg_profile;
+ struct device_node *node = batt_drv->device->of_node;
+ int err;
+
+ /* reset AACT */
+ aact_reset(profile);
+
+ /* set state to unknown and init default charge table */
+ batt_drv->aact_state = BATT_AACT_UNKNOWN;
+ err = gbms_init_chg_profile(profile, node);
+ if (err == 0)
+ gbms_init_chg_table(profile, node, aacr_get_capacity(batt_drv));
+
+ mutex_unlock(&batt_drv->aact_state_lock);
+ return ret;
+ }
+
+done:
+ mutex_unlock(&batt_drv->aact_state_lock);
+ return count;
+}
+
+static ssize_t aact_state_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct power_supply *psy = container_of(dev, struct power_supply, dev);
+ struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+
+ return scnprintf(buf, PAGE_SIZE, "%d\n", batt_drv->aact_state);
+}
+
+static const DEVICE_ATTR_RW(aact_state);
+
+/* AACP ------------------------------------------------------------------- */
+
+static ssize_t aacp_version_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct power_supply *psy = container_of(dev, struct power_supply, dev);
+ struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+ int value, ret = 0;
+
+ ret = kstrtoint(buf, 0, &value);
+ if (ret < 0)
+ return ret;
+
+ if (value >= 0)
+ batt_drv->aacp_version = value;
+
+ return count;
+}
+
+static ssize_t aacp_version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct power_supply *psy = container_of(dev, struct power_supply, dev);
+ struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+
+ return scnprintf(buf, PAGE_SIZE, "%d\n", batt_drv->aacp_version);
+}
+
+static const DEVICE_ATTR_RW(aacp_version);
+
+/* AACC ------------------------------------------------------------------- */
+
+static ssize_t aacc_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct power_supply *psy = container_of(dev, struct power_supply, dev);
+ struct batt_drv *batt_drv = power_supply_get_drvdata(psy);
+
+ return scnprintf(buf, PAGE_SIZE, "%d\n", batt_drv->aacc);
+}
+
+static const DEVICE_ATTR_RO(aacc);
+
/* Swelling --------------------------------------------------------------- */
static ssize_t swelling_data_show(struct device *dev,
@@ -9358,6 +9593,18 @@
ret = device_create_file(&batt_drv->psy->dev, &dev_attr_aafv_offset);
if (ret)
dev_err(&batt_drv->psy->dev, "Failed to create aafv offset\n");
+ /* aact */
+ ret = device_create_file(&batt_drv->psy->dev, &dev_attr_aact_state);
+ if (ret)
+ dev_err(&batt_drv->psy->dev, "Failed to create aact state\n");
+ /* aacp */
+ ret = device_create_file(&batt_drv->psy->dev, &dev_attr_aacp_version);
+ if (ret)
+ dev_err(&batt_drv->psy->dev, "Failed to create aacp version\n");
+ /* aacc */
+ ret = device_create_file(&batt_drv->psy->dev, &dev_attr_aacc);
+ if (ret)
+ dev_err(&batt_drv->psy->dev, "Failed to create aacc\n");
/* health and health index */
ret = device_create_file(&batt_drv->psy->dev, &dev_attr_swelling_data);
@@ -9478,16 +9725,16 @@
debugfs_create_u32("blf_collect_now", 0600, de, &batt_drv->blf_collect_now);
/* defender */
- debugfs_create_u32("fake_capacity", 0600, de,
- &batt_drv->fake_capacity);
+ debugfs_create_u32("fake_capacity", 0600, de, &batt_drv->fake_capacity);
/* aacr test */
- debugfs_create_u32("fake_aacr_cc", 0600, de,
- &batt_drv->fake_aacr_cc);
+ debugfs_create_u32("fake_aacr_cc", 0600, de, &batt_drv->fake_aacr_cc);
/* aafv test */
- debugfs_create_u32("fake_aafv_cc", 0600, de,
- &batt_drv->fake_aafv_cc);
+ debugfs_create_u32("fake_aafv_cc", 0600, de, &batt_drv->fake_aafv_cc);
+
+ /* aact test */
+ debugfs_create_u32("fake_aact_cc", 0600, de, &batt_drv->fake_aact_cc);
/* health charging (adaptive charging) */
debugfs_create_file("chg_health_thr_soc", 0600, de, batt_drv,
@@ -11427,6 +11674,7 @@
mutex_init(&batt_drv->hda_tz_lock);
mutex_init(&batt_drv->aacr_state_lock);
mutex_init(&batt_drv->aafv_state_lock);
+ mutex_init(&batt_drv->aact_state_lock);
ret = of_property_read_u32(node, "google,batt-init-delay", &init_delay_ms);
if (ret < 0)
@@ -11975,6 +12223,12 @@
batt_drv->aafv_cliff_cycle = AAFV_CLIFF_CYCLE_DEFAULT;
batt_drv->aafv_cliff_offset = AAFV_CLIFF_OFFSET_DEFAULT;
+ /* AACT server side */
+ batt_drv->aact_state = BATT_AACT_DISABLED;
+
+ /* AACP default version */
+ batt_drv->aacp_version = 1;
+
/* create the sysfs node */
batt_init_fs(batt_drv);
batt_bpst_init_fs(batt_drv);
diff --git a/google_bms.c b/google_bms.c
index a2e13d0..328ea64 100644
--- a/google_bms.c
+++ b/google_bms.c
@@ -151,21 +151,33 @@
u32 ccm;
int vi, ti, ret;
const int cc_ua_step = profile->cc_ua_resolution;
+ int temp_nb_count = profile->temp_nb_limits - 1;
u32 cccm_array_size = (profile->temp_nb_limits - 1)
* profile->volt_nb_limits;
profile->capacity_ma = capacity_ma;
- ret = of_property_read_u32_array(node, "google,chg-cc-limits",
- profile->cccm_limits,
- cccm_array_size);
+ if (!profile->aact_init_profile) {
+ ret = of_property_read_u32_array(node, "google,chg-cc-limits",
+ profile->cccm_limits,
+ cccm_array_size);
+ } else {
+ temp_nb_count = (profile->temp_nb_limits - 1) * profile->aact_nb_limits;
+ cccm_array_size = (profile->temp_nb_limits - 1)
+ * profile->volt_nb_limits
+ * profile->aact_nb_limits;
+ ret = of_property_read_u32_array(node, "google,aact-cc-limits",
+ profile->cccm_limits,
+ cccm_array_size);
+ }
+
if (ret < 0)
pr_warn("unable to get default cccm_limits.\n");
/* chg-battery-capacity is in mAh, chg-cc-limits relative to 100 */
- for (ti = 0; ti < profile->temp_nb_limits - 1; ti++) {
+ for (ti = 0; ti < temp_nb_count; ti++) {
for (vi = 0; vi < profile->volt_nb_limits; vi++) {
- ccm = GBMS_CCCM_LIMITS(profile, ti, vi);
+ ccm = GBMS_CCCM_LIMITS_GET(profile, ti, vi);
ccm *= capacity_ma * 10;
/* round to the nearest resolution */
@@ -388,7 +400,6 @@
}
EXPORT_SYMBOL_GPL(gbms_read_aafv_limits);
-/* return the pct amount of capacity fade at cycles or negative if not enabled */
int gbms_aafv_get_offset(const struct gbms_chg_profile *profile, const int cycles)
{
int idx;
@@ -520,6 +531,8 @@
profile->volt_limits[vi] = profile->volt_limits[vi] /
profile->fv_uv_resolution * profile->fv_uv_resolution;
+ /* reset AACT */
+ profile->aact_init_profile = false;
return 0;
}
EXPORT_SYMBOL_GPL(gbms_init_chg_profile_internal);
@@ -531,6 +544,126 @@
}
EXPORT_SYMBOL_GPL(gbms_free_chg_profile);
+static int gbms_read_aact_cccm_limits(struct gbms_chg_profile *profile,
+ struct device_node *node)
+{
+ int ret;
+
+ profile->temp_nb_limits =
+ of_property_count_elems_of_size(node, "google,aact-temp-limits",
+ sizeof(u32));
+ if (profile->temp_nb_limits <= 0) {
+ ret = profile->temp_nb_limits;
+ gbms_err(profile, "cannot read aact-temp-limits, ret=%d\n", ret);
+ return -EINVAL;
+ }
+ if (profile->temp_nb_limits > GBMS_CHG_TEMP_NB_LIMITS_MAX) {
+ gbms_err(profile, "aact-temp-nb-limits exceeds driver max: %d\n",
+ GBMS_CHG_TEMP_NB_LIMITS_MAX);
+ return -EINVAL;
+ }
+ ret = of_property_read_u32_array(node, "google,aact-temp-limits",
+ (u32 *)profile->temp_limits,
+ profile->temp_nb_limits);
+ if (ret < 0) {
+ gbms_err(profile, "cannot read aact-temp-limits table, ret=%d\n", ret);
+ return ret;
+ }
+
+ profile->volt_nb_limits =
+ of_property_count_elems_of_size(node, "google,aact-cv-limits",
+ sizeof(u32));
+ if (profile->volt_nb_limits <= 0) {
+ ret = profile->volt_nb_limits;
+ gbms_err(profile, "cannot read aact-cv-limits, ret=%d\n", ret);
+ return -EINVAL;
+ }
+ if (profile->volt_nb_limits > GBMS_CHG_VOLT_NB_LIMITS_MAX) {
+ gbms_err(profile, "aact-cv-nb-limits exceeds driver max: %d\n",
+ GBMS_CHG_VOLT_NB_LIMITS_MAX);
+ return -EINVAL;
+ }
+ ret = of_property_read_u32_array(node, "google,aact-cv-limits",
+ (u32 *)profile->volt_limits,
+ profile->volt_nb_limits);
+ if (ret < 0) {
+ gbms_err(profile, "cannot read aact-cv-limits table, ret=%d\n", ret);
+ return ret;
+ }
+
+ profile->aact_nb_limits =
+ of_property_count_elems_of_size(node, "google,chg-aact-ecc",
+ sizeof(u32));
+ if (profile->aact_nb_limits <= 0) {
+ ret = profile->aact_nb_limits;
+ gbms_err(profile, "cannot read chg-aact-ecc, ret=%d\n", ret);
+ return -EINVAL;
+ }
+ if (profile->aact_nb_limits > GBMS_AACT_NB_LIMITS_MAX) {
+ gbms_err(profile, "chg-aact-ecc exceeds driver max: %d\n",
+ GBMS_AACT_NB_LIMITS_MAX);
+ return -EINVAL;
+ }
+ ret = of_property_read_u32_array(node, "google,chg-aact-ecc",
+ (u32 *)profile->aact_limits,
+ profile->aact_nb_limits);
+ if (ret < 0) {
+ gbms_err(profile, "cannot read aact-cv-limits table, ret=%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int gbms_init_aact_profile_internal(struct gbms_chg_profile *profile,
+ struct device_node *node,
+ const char *owner_name)
+{
+ int ret;
+ u32 cccm_array_size, mem_size;
+
+ profile->owner_name = owner_name;
+
+ ret = gbms_read_aact_cccm_limits(profile, node);
+ if (ret < 0)
+ return ret;
+
+ cccm_array_size = (profile->temp_nb_limits - 1)
+ * profile->volt_nb_limits
+ * profile->aact_nb_limits;
+ mem_size = sizeof(s32) * cccm_array_size;
+
+ profile->cccm_limits = kzalloc(mem_size, GFP_KERNEL);
+ if (!profile->cccm_limits)
+ return -ENOMEM;
+
+ /* load C rates into profile->cccm_limits */
+ ret = of_property_read_u32_array(node, "google,aact-cc-limits",
+ profile->cccm_limits,
+ cccm_array_size);
+ if (ret < 0) {
+ gbms_err(profile, "cannot read aact-cc-limits table, ret=%d\n", ret);
+ kfree(profile->cccm_limits);
+ profile->cccm_limits = 0;
+ return -EINVAL;
+ }
+
+ profile->aact_init_profile = true;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(gbms_init_aact_profile_internal);
+
+int gbms_aact_get_index(const struct gbms_chg_profile *profile, const int cycles)
+{
+ int idx = 0;
+
+ while (idx <= profile->aact_nb_limits - 1 && cycles >= profile->aact_limits[idx])
+ idx++;
+
+ return idx - 1;
+}
+EXPORT_SYMBOL_GPL(gbms_aact_get_index);
+
/* NOTE: I should really pass the scale */
void gbms_dump_raw_profile(char *buff, size_t len, const struct gbms_chg_profile *profile, int scale)
{
@@ -614,16 +747,15 @@
{
int cc_max;
int vbatt_idx = 0;
- const int vbatt_last_idx = gbms_msc_get_last_voltage_idx(profile, temp_idx);
if (!profile)
return 0;
- while (vbatt_idx < vbatt_last_idx &&
+ while (vbatt_idx < profile->volt_nb_limits - 1 &&
vbatt > profile->volt_limits[vbatt_idx])
vbatt_idx++;
- if (vbatt_idx != vbatt_last_idx) {
+ if (vbatt_idx != profile->volt_nb_limits - 1) {
const int vt = profile->volt_limits[vbatt_idx];
const int headr = profile->fv_uv_resolution * 3;
@@ -635,7 +767,7 @@
return vbatt_idx;
cc_max = GBMS_CCCM_LIMITS(profile, temp_idx, vbatt_idx);
- while (vbatt_idx < vbatt_last_idx - 1 &&
+ while (vbatt_idx < profile->volt_nb_limits - 2 &&
cc_max == GBMS_CCCM_LIMITS(profile, temp_idx, vbatt_idx + 1))
vbatt_idx++;
diff --git a/google_bms.h b/google_bms.h
index 58b71ad..8947fff 100644
--- a/google_bms.h
+++ b/google_bms.h
@@ -37,6 +37,7 @@
#define GBMS_CHG_TOPOFF_NB_LIMITS_MAX 6
#define GBMS_AACR_DATA_MAX 10
#define GBMS_AAFV_DATA_MAX 16
+#define GBMS_AACT_NB_LIMITS_MAX 10
struct gbms_chg_profile {
const char *owner_name;
@@ -78,6 +79,12 @@
u32 aafv_nb_limits;
u32 aafv_offset;
+ /* AACT feature */
+ int aact_nb_limits;
+ s32 aact_limits[GBMS_AACT_NB_LIMITS_MAX];
+ int aact_idx;
+ bool aact_init_profile;
+
bool debug_chg_profile;
bool enable_switch_chg_profile;
};
@@ -402,6 +409,9 @@
uint16_t csi_aggregate_status;
uint16_t csi_aggregate_type;
+ int aacp_version;
+ int aacc;
+
/* health based charging */
struct batt_chg_health ce_health; /* updated on close */
struct gbms_ce_tier_stats health_stats; /* updated in HC */
@@ -422,9 +432,16 @@
#define GBMS_CCCM_LIMITS_SET(profile, ti, vi) \
profile->cccm_limits[((ti) * profile->volt_nb_limits) + (vi)]
-#define GBMS_CCCM_LIMITS(profile, ti, vi) \
+#define GBMS_CCCM_LIMITS_GET(profile, ti, vi) \
(((ti) >= 0 && (vi) >= 0) ? profile->cccm_limits[((ti) * profile->volt_nb_limits) + (vi)] : 0)
+#define GBMS_AACT_IDX(profile) \
+ (profile->aact_idx * (profile->temp_nb_limits - 1))
+
+#define GBMS_CCCM_LIMITS(profile, ti, vi) \
+ (((ti) >= 0 && (vi) >= 0) ? \
+ profile->cccm_limits[((ti + GBMS_AACT_IDX(profile)) * profile->volt_nb_limits) + (vi)] : 0)
+
/* newgen charging */
#define GBMS_CS_FLAG_BUCK_EN BIT(0)
#define GBMS_CS_FLAG_DONE BIT(1)
@@ -452,6 +469,11 @@
struct device_node *node, const char *owner_name);
#define gbms_init_chg_profile(p, n) \
gbms_init_chg_profile_internal(p, n, KBUILD_MODNAME)
+int gbms_init_aact_profile_internal(struct gbms_chg_profile *profile,
+ struct device_node *node, const char *owner_name);
+#define gbms_init_aact_profile(p, n) \
+ gbms_init_aact_profile_internal(p, n, KBUILD_MODNAME)
+int gbms_aact_get_index(const struct gbms_chg_profile *profile, const int cycles);
void gbms_init_chg_table(struct gbms_chg_profile *profile,
struct device_node *node, u32 capacity);
diff --git a/google_dual_batt_gauge.c b/google_dual_batt_gauge.c
index 73eb7b0..ce01e3f 100644
--- a/google_dual_batt_gauge.c
+++ b/google_dual_batt_gauge.c
@@ -828,6 +828,7 @@
case GBMS_PROP_CAPACITY_FADE_RATE:
case GBMS_PROP_CAPACITY_FADE_RATE_FCR:
case GBMS_PROP_BATT_ID:
+ case GBMS_PROP_AAFV:
val->prop.intval = fg_1.prop.intval;
break;
case GBMS_PROP_RECAL_FG:
@@ -894,6 +895,18 @@
case GBMS_PROP_RECAL_FG:
/* TODO: under porting */
break;
+ case GBMS_PROP_AAFV:
+ if (dual_fg_drv->first_fg_psy) {
+ ret = GPSY_SET_PROP(dual_fg_drv->first_fg_psy, psp, val->prop.intval);
+ if (ret < 0)
+ pr_err("Cannot set aafv to the first FG, ret=%d\n", ret);
+ }
+ if (dual_fg_drv->second_fg_psy) {
+ ret = GPSY_SET_PROP(dual_fg_drv->second_fg_psy, psp, val->prop.intval);
+ if (ret < 0)
+ pr_err("Cannot set aafv to the second FG, ret=%d\n", ret);
+ }
+ break;
default:
pr_debug("%s: route to gdbatt_set_property, psp:%d\n", __func__, psp);
return -ENODATA;
@@ -912,6 +925,7 @@
{
switch (psp) {
case GBMS_PROP_BATT_CE_CTRL:
+ case GBMS_PROP_AAFV:
return 1;
default:
break;
@@ -966,7 +980,7 @@
/* chg-battery-capacity is in mAh, chg-cc-limits relative to 100 */
for (ti = 0; ti < pack_profile->temp_nb_limits - 1; ti++) {
for (vi = 0; vi < pack_profile->volt_nb_limits; vi++) {
- ccm = GBMS_CCCM_LIMITS(pack_profile, ti, vi);
+ ccm = GBMS_CCCM_LIMITS_GET(pack_profile, ti, vi);
ccm *= capacity_ma * 10;
GBMS_CCCM_LIMITS_SET(pack_profile, ti, vi) = ccm;
diff --git a/max1720x_battery.c b/max1720x_battery.c
index 4833bad..8aef260 100644
--- a/max1720x_battery.c
+++ b/max1720x_battery.c
@@ -243,6 +243,9 @@
/* buffer for recording learning history */
struct maxfg_capture_buf cb_lh;
+
+ /* AAFV: Aged Adjusted Float Voltage */
+ int aafv;
};
#define MAX1720_EMPTY_VOLTAGE(profile, temp, cycle) \
@@ -2699,6 +2702,9 @@
if (chip->gauge_type == MAX_M5_GAUGE_TYPE)
val->prop.intval = max_m5_recal_state(chip->model_data);
break;
+ case GBMS_PROP_AAFV:
+ val->prop.intval = chip->aafv;
+ break;
default:
pr_debug("%s: route to max1720x_get_property, psp:%d\n", __func__, psp);
err = -ENODATA;
@@ -2781,6 +2787,9 @@
case GBMS_PROP_RECAL_FG:
max1720x_set_recalibration(chip, val->prop.intval);
break;
+ case GBMS_PROP_AAFV:
+ chip->aafv = val->prop.intval;
+ break;
default:
pr_debug("%s: route to max1720x_set_property, psp:%d\n", __func__, psp);
return -ENODATA;
@@ -2798,6 +2807,7 @@
switch (psp) {
case GBMS_PROP_BATT_CE_CTRL:
case GBMS_PROP_HEALTH_ACT_IMPEDANCE:
+ case GBMS_PROP_AAFV:
return 1;
default:
break;
diff --git a/max77779_fg.c b/max77779_fg.c
index e3f26b0..a05aecf 100644
--- a/max77779_fg.c
+++ b/max77779_fg.c
@@ -1673,6 +1673,9 @@
case GBMS_PROP_RECAL_FG:
/* TODO: under porting */
break;
+ case GBMS_PROP_AAFV:
+ val->prop.intval = chip->aafv;
+ break;
default:
pr_debug("%s: route to max77779_fg_get_property, psp:%d\n", __func__, psp);
err = -ENODATA;
@@ -1745,6 +1748,9 @@
case GBMS_PROP_RECAL_FG:
/* TODO: under porting */
break;
+ case GBMS_PROP_AAFV:
+ chip->aafv = val->prop.intval;
+ break;
default:
pr_debug("%s: route to max77779_fg_set_property, psp:%d\n", __func__, psp);
return -ENODATA;
@@ -1762,6 +1768,7 @@
switch (psp) {
case GBMS_PROP_BATT_CE_CTRL:
case GBMS_PROP_HEALTH_ACT_IMPEDANCE:
+ case GBMS_PROP_AAFV:
return 1;
default:
break;
diff --git a/max77779_fg.h b/max77779_fg.h
index 5e3d4e2..bc79522 100644
--- a/max77779_fg.h
+++ b/max77779_fg.h
@@ -194,6 +194,9 @@
/* mutex lock to access FG USR reg */
struct mutex usr_lock;
+
+ /* AAFV: Aged Adjusted Float Voltage */
+ int aafv;
};
/** ------------------------------------------------------------------------ */