summaryrefslogtreecommitdiff
path: root/common/charge_state_v2.c
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2020-04-03 17:18:53 -0700
committerJustin TerAvest <teravest@chromium.org>2020-06-02 17:25:42 +0000
commit7229fab3bb2d4c1983dab388210eb894855aec7d (patch)
tree2e7dae00b9ed961f5929cc982f8aa0057f918c94 /common/charge_state_v2.c
parentdba753130cd341c047afd652ab28a2b099dde9ee (diff)
downloadchrome-ec-7229fab3bb2d4c1983dab388210eb894855aec7d.tar.gz
OCPC: Configure VSYS via secondary charger IC
This commit adds the bulk of the work in getting OCPC functional. Since the secondary charger IC cannot directly sense the current entering the battery, with OCPC, we recruit the EC to do this work instead. Essentially, VSYS needs to be chosen such that we induce the desired current in the battery while also accounting for losses in the system between the output of the secondary charger IC and the battery. To start, a board needs to define the following CONFIG_* option: CONFIG_OCPC_DEF_RBATT_MOHMS This should be at least the R_ds(on) resistance of the BFET and the series sense resistance. The board should also define CONFIG_OCPC. With the combined system resistance, we can calculate the VSYS required to induce the desired current. However, we will also use a PID control loop to help drive our VSYS target to what it should actually be accounting for our error. The PID constants were found by tuning on a waddledoo board. It remains to be seen whether or not these will differ on a board to board basis. BUG=b:148980016,b:147440290 BRANCH=None TEST=Enable on waddledoo, verify that we can charge the battery from the sub-board. Signed-off-by: Aseda Aboagye <aaboagye@google.com> Change-Id: Icd323546836fe41fa1fcc7c3b6071d822663ed05 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2135964 Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org> Commit-Queue: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'common/charge_state_v2.c')
-rw-r--r--common/charge_state_v2.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index 6354cf0a40..ce5b826c8f 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -164,6 +164,7 @@ enum problem_type {
PR_CHG_FLAGS,
PR_BATT_FLAGS,
PR_CUSTOM,
+ PR_CFG_SEC_CHG,
NUM_PROBLEM_TYPES
};
@@ -177,6 +178,7 @@ static const char * const prob_text[] = {
"chg params",
"batt params",
"custom profile",
+ "cfg secondary chg"
};
BUILD_ASSERT(ARRAY_SIZE(prob_text) == NUM_PROBLEM_TYPES);
@@ -1080,6 +1082,15 @@ static void dump_charge_state(void)
#ifdef CONFIG_OCPC
ccprintf("ocpc.*:\n");
DUMP_OCPC(active_chg_chip, "%d");
+ DUMP_OCPC(combined_rsys_rbatt_mo, "%dmOhm");
+ DUMP_OCPC(primary_vbus_mv, "%dmV");
+ DUMP_OCPC(primary_ibus_ma, "%dmA");
+ DUMP_OCPC(secondary_vbus_mv, "%dmV");
+ DUMP_OCPC(secondary_ibus_ma, "%dmA");
+ DUMP_OCPC(last_error, "%d");
+ DUMP_OCPC(integral, "%d");
+ DUMP_OCPC(last_vsys, "%dmV");
+ cflush();
#endif /* CONFIG_OCPC */
DUMP(requested_voltage, "%dmV");
DUMP(requested_current, "%dmA");
@@ -1195,7 +1206,7 @@ static int calc_is_full(void)
*/
static int charge_request(int voltage, int current)
{
- int r1 = EC_SUCCESS, r2 = EC_SUCCESS, r3 = EC_SUCCESS;
+ int r1 = EC_SUCCESS, r2 = EC_SUCCESS, r3 = EC_SUCCESS, r4 = EC_SUCCESS;
static int __bss_slow prev_volt, prev_curr;
if (!voltage || !current) {
@@ -1240,22 +1251,43 @@ static int charge_request(int voltage, int current)
if (r1 != EC_SUCCESS)
problem(PR_SET_VOLTAGE, r1);
+#ifdef CONFIG_OCPC
+ /*
+ * For OCPC systems, if the secondary charger is active, we need to
+ * configure that charge IC as well. Note that if OCPC ever supports
+ * more than 2 charger ICs, we'll need to refactor things a bit. The
+ * following check should be comparing against PRIMARY_CHARGER and
+ * config_secondary_charger should probably be config_auxiliary_charger
+ * and take the active chgnum as a parameter.
+ */
+ if (curr.ocpc.active_chg_chip == SECONDARY_CHARGER) {
+ if ((current >= 0) || (voltage >= 0))
+ r3 = ocpc_config_secondary_charger(&curr.desired_input_current,
+ &curr.ocpc,
+ voltage, current);
+ if (r3 != EC_SUCCESS)
+ problem(PR_CFG_SEC_CHG, r3);
+ }
+#endif /* CONFIG_OCPC */
+
/*
* Set the charge inhibit bit when possible as it appears to save
* power in some cases (e.g. Nyan with BQ24735).
*/
if (voltage > 0 || current > 0)
- r3 = charger_set_mode(0);
+ r4 = charger_set_mode(0);
else
- r3 = charger_set_mode(CHARGE_FLAG_INHIBIT_CHARGE);
- if (r3 != EC_SUCCESS)
- problem(PR_SET_MODE, r3);
+ r4 = charger_set_mode(CHARGE_FLAG_INHIBIT_CHARGE);
+ if (r4 != EC_SUCCESS)
+ problem(PR_SET_MODE, r4);
/*
* Only update if the request worked, so we'll keep trying on failures.
*/
if (r1 || r2)
return r1 ? r1 : r2;
+ if (IS_ENABLED(CONFIG_OCPC) && r3)
+ return r3;
if (IS_ENABLED(CONFIG_USB_PD_PREFER_MV) &&
(prev_volt != voltage || prev_curr != current))
@@ -1630,6 +1662,15 @@ void charger_task(void *u)
battery_dynamic[BATT_IDX_BASE].flags = EC_BATT_FLAG_INVALID_DATA;
charge_base = -1;
#endif
+#ifdef CONFIG_OCPC
+ /*
+ * We can start off assuming that the board resistance is 0 ohms
+ * and later on, we can update this value if we charge the
+ * system in suspend or off.
+ */
+ curr.ocpc.combined_rsys_rbatt_mo = CONFIG_OCPC_DEF_RBATT_MOHMS;
+ charge_set_active_chg_chip(CHARGE_PORT_NONE);
+#endif /* CONFIG_OCPC */
/*
* If system is not locked and we don't have a battery to live on,
@@ -1713,6 +1754,9 @@ void charger_task(void *u)
charger_get_params(&curr.chg);
battery_get_params(&curr.batt);
+#ifdef CONFIG_OCPC
+ ocpc_get_adcs(&curr.ocpc);
+#endif /* CONFIG_OCPC */
if (prev_bp != curr.batt.is_present) {
prev_bp = curr.batt.is_present;
@@ -2435,6 +2479,11 @@ void charge_set_active_chg_chip(int idx)
CPRINTS("Act Chg: %d", idx);
curr.ocpc.active_chg_chip = idx;
+ if (idx == CHARGE_PORT_NONE) {
+ curr.ocpc.last_error = 0;
+ curr.ocpc.integral = 0;
+ curr.ocpc.last_vsys = OCPC_UNINIT;
+ }
}
#endif /* CONFIG_OCPC */