summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2018-11-01 09:53:31 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-09-12 21:40:08 +0000
commitcc6d611dc25d85633b8b91b70dc26d7d82ac4854 (patch)
treeccf2d1d688b5fa04fb8cfe04d0597eaddee0309b
parentebf0318eafd2c50d31a8b84a81c371c5de3851a6 (diff)
downloadchrome-ec-cc6d611dc25d85633b8b91b70dc26d7d82ac4854.tar.gz
Battery: Compensate remaining charge to match full capacity
If remaining charge is more than x% of the full capacity, the remaining charge is raised to the full capacity before it's reported to the rest of the system. Some batteries don't update full capacity timely or don't update it at all. On such systems, compensation is required to guarantee the remaining charge will be equal to the full capacity eventually. On some systems, Rohm charger generates audio noise when the battery is fully charged and AC is plugged. A workaround is to do charge- discharge cycles between 93 and 100%. On such systems, compensation was also applied to mask this cycle from users. This used to be done in ACPI, thus, all software components except EC was able to see the compensated charge. This patch is moving the logic to EC. With this and the following changes, EC can see what the rest of the system sees, thus, can control LEDs synchronously (to the display percentage). Another rationale of this move is EC can perform more granular and precise compensation than ACPI since it has more knowledge about the battery and the charger. Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> CQ-DEPEND=CL:3880010 BUG=b:109954565,b:80270446 BRANCH=none TEST=Verify charge LED changes to white (full) on Sona synchronously to the display percentage. TEST=Verify charge LED changes to blinking white (low) on Sona within 30 seconds synchronously to the display percentage. Change-Id: I4e3f70efa39e62c91cb8894b603c551cd23511aa Reviewed-on: https://chromium-review.googlesource.com/1312204 Commit-Ready: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3869317 Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org> Auto-Submit: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--common/battery.c22
-rw-r--r--driver/battery/smart.c2
-rw-r--r--include/battery.h24
-rw-r--r--include/config.h14
-rw-r--r--test/battery_get_params_smart.c5
5 files changed, 67 insertions, 0 deletions
diff --git a/common/battery.c b/common/battery.c
index 9d7277479c..9d380efe86 100644
--- a/common/battery.c
+++ b/common/battery.c
@@ -21,6 +21,12 @@
#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
+/*
+ * See config.h for details.
+ * TODO: Allow host (powerd) to update it.
+ */
+static int batt_full_factor = CONFIG_BATT_FULL_FACTOR;
+
#ifdef CONFIG_BATTERY_V2
/*
* Store battery information in these 2 structures. Main (lid) battery is always
@@ -557,6 +563,22 @@ DECLARE_HOOK(HOOK_INIT, battery_init, HOOK_PRIO_DEFAULT);
#endif /* HAS_TASK_HOSTCMD */
#endif /* CONFIG_BATTERY_V2 */
+void battery_compensate_params(struct batt_params *batt)
+{
+ int remain = batt->remaining_capacity;
+ int full = batt->full_capacity;
+
+ if ((batt->flags & BATT_FLAG_BAD_FULL_CAPACITY) ||
+ (batt->flags & BATT_FLAG_BAD_REMAINING_CAPACITY))
+ return;
+
+ if (remain <= 0 || full <= 0)
+ return;
+
+ if (remain * 100 > full * batt_full_factor)
+ batt->remaining_capacity = full;
+}
+
__attribute__((weak)) int get_battery_manufacturer_name(char *dest, int size)
{
strzcpy(dest, "<unkn>", size);
diff --git a/driver/battery/smart.c b/driver/battery/smart.c
index 90abbe80a8..fd27e55ab9 100644
--- a/driver/battery/smart.c
+++ b/driver/battery/smart.c
@@ -395,6 +395,8 @@ void battery_get_params(struct batt_params *batt)
/* Force both to zero */
batt_new.desired_voltage = batt_new.desired_current = 0;
+ battery_compensate_params(&batt_new);
+
/* Update visible battery parameters */
memcpy(batt, &batt_new, sizeof(*batt));
}
diff --git a/include/battery.h b/include/battery.h
index 30ec6fdab7..805dc851c9 100644
--- a/include/battery.h
+++ b/include/battery.h
@@ -414,4 +414,28 @@ void battery_memmap_set_index(enum battery_index index);
extern struct i2c_stress_test_dev battery_i2c_stress_test_dev;
#endif
+/*
+ * If remaining charge is more than x% of the full capacity, the
+ * remaining charge is raised to the full capacity before it's
+ * reported to the rest of the system.
+ *
+ * Some batteries don't update full capacity timely or don't update it
+ * at all. On such systems, compensation is required to guarantee
+ * the remaining charge will be equal to the full capacity eventually.
+ *
+ * On some systems, Rohm charger generates audio noise when the battery
+ * is fully charged and AC is plugged. A workaround is to do charge-
+ * discharge cycles between 93 and 100%. On such systems, compensation
+ * was also applied to mask this cycle from users.
+ *
+ * This used to be done in ACPI, thus, all software components except EC
+ * was seeing the compensated charge. Now we do it in EC. It has more
+ * knowledge on the charger and the battery. So, it can perform more
+ * granular and precise compensation.
+ *
+ * TODO: Currently, this is applied only to smart battery. Apply it to other
+ * battery drivers as needed.
+ */
+void battery_compensate_params(struct batt_params *batt);
+
#endif /* __CROS_EC_BATTERY_H */
diff --git a/include/config.h b/include/config.h
index e6a72b0d7f..d732145fae 100644
--- a/include/config.h
+++ b/include/config.h
@@ -492,6 +492,20 @@
#undef CONFIG_BATTERY_MEASURE_IMBALANCE
/*
+ * If remaining capacity is x% of full capacity, remaining capacity is set
+ * equal to full capacity.
+ *
+ * Some batteries don't update full capacity timely or don't update it at all.
+ * On such systems, compensation is required to guarantee remaining_capacity
+ * will be equal to full_capacity eventually. This used to be done in ACPI.
+ *
+ * This number should match those used by powerd to evenly scale battery
+ * reading from 0 to 100%. These are default values, which are effective until
+ * the host boots.
+ */
+#define CONFIG_BATT_FULL_FACTOR 98
+
+/*
* Expose some data when it is needed.
* For example, battery disconnect state
*/
diff --git a/test/battery_get_params_smart.c b/test/battery_get_params_smart.c
index 316424e080..c44cd64e56 100644
--- a/test/battery_get_params_smart.c
+++ b/test/battery_get_params_smart.c
@@ -19,6 +19,11 @@ static int fail_on_first, fail_on_last;
static int read_count, write_count;
struct batt_params batt;
+
+void battery_compensate_params(struct batt_params *batt)
+{
+}
+
static void reset_and_fail_on(int first, int last)
{
/* We're not initializing the fake battery, so everything reads zero */