summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYilun Lin <yllin@chromium.org>2019-11-19 15:01:55 +0800
committerCommit Bot <commit-bot@chromium.org>2019-11-21 21:25:41 +0000
commit6b04974671e900846c92d0e02cbcfeeac7158c07 (patch)
tree462fcfdb744c53da21ced5163fe7348487228ac1
parenta5e34f327ae08e0e77e78f94f4f725ea9ab6f374 (diff)
downloadchrome-ec-6b04974671e900846c92d0e02cbcfeeac7158c07.tar.gz
charger/rt946x: fix mt6370 IEOC inaccuracy
mt6370's IEOC is inaccurate when charging current < 900mA; the power path only partially turned on under such situation. Hence, we have to raise the IEOC setting if the current is under 900mA to compensate the IEOC original setting. BUG=b:144532905 BRANCH=kukui TEST=ensure IEOC is raised when Ichg < 900mA. Change-Id: I9f1575bb707bc91e428c06a93c4682dde22d90fc Signed-off-by: Yilun Lin <yllin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1924167 Reviewed-by: Ting Shen <phoenixshen@chromium.org>
-rw-r--r--driver/charger/rt946x.c71
1 files changed, 63 insertions, 8 deletions
diff --git a/driver/charger/rt946x.c b/driver/charger/rt946x.c
index 589dda1960..342aa704f7 100644
--- a/driver/charger/rt946x.c
+++ b/driver/charger/rt946x.c
@@ -263,6 +263,21 @@ static inline uint8_t rt946x_closest_reg(uint16_t min, uint16_t max,
return (target - min) / step;
}
+static int rt946x_get_ieoc(uint32_t *ieoc)
+{
+ int ret, reg_ieoc;
+
+ ret = rt946x_read8(RT946X_REG_CHGCTRL9, &reg_ieoc);
+ if (ret)
+ return ret;
+
+ *ieoc = RT946X_IEOC_MIN +
+ RT946X_IEOC_STEP *
+ ((reg_ieoc & RT946X_MASK_IEOC) >> RT946X_SHIFT_IEOC);
+
+ return EC_SUCCESS;
+}
+
#ifdef CONFIG_CHARGER_MT6370
static int mt6370_enable_hidden_mode(int en)
{
@@ -382,15 +397,15 @@ static int rt946x_enable_bc12_detection(int en)
static int rt946x_set_ieoc(unsigned int ieoc)
{
- uint8_t reg_ieoc = 0;
+ uint8_t reg_ieoc;
reg_ieoc = rt946x_closest_reg(RT946X_IEOC_MIN, RT946X_IEOC_MAX,
- RT946X_IEOC_STEP, ieoc);
+ RT946X_IEOC_STEP, ieoc);
CPRINTF("%s ieoc = %d(0x%02X)\n", __func__, ieoc, reg_ieoc);
return rt946x_update_bits(RT946X_REG_CHGCTRL9, RT946X_MASK_IEOC,
- reg_ieoc << RT946X_SHIFT_IEOC);
+ reg_ieoc << RT946X_SHIFT_IEOC);
}
static int rt946x_set_mivr(unsigned int mivr)
@@ -757,14 +772,54 @@ int charger_get_current(int *current)
int charger_set_current(int current)
{
- uint8_t reg_icc = 0;
- const struct charger_info * const info = charger_get_info();
+ int rv;
+ uint8_t reg_icc;
+ static int workaround;
+ const struct charger_info *const info = charger_get_info();
+
+ /*
+ * mt6370's minimun regulated current is 500mA REG17[7:2] 0b100,
+ * values below 0b100 are preserved.
+ */
+ if (IS_ENABLED(CONFIG_CHARGER_MT6370))
+ current = MAX(500, current);
+
reg_icc = rt946x_closest_reg(info->current_min, info->current_max,
- info->current_step, current);
+ info->current_step, current);
+
+ rv = rt946x_update_bits(RT946X_REG_CHGCTRL7, RT946X_MASK_ICHG,
+ reg_icc << RT946X_SHIFT_ICHG);
+ if (rv)
+ return rv;
+
+ if (IS_ENABLED(CONFIG_CHARGER_RT9466) ||
+ IS_ENABLED(CONFIG_CHARGER_MT6370)) {
+ uint32_t curr_ieoc;
+
+ /*
+ * workaround to make IEOC accurate:
+ * witht normal charging (ICC >= 900mA), the power path is fully
+ * turned on. But at low charging current state (ICC < 900mA),
+ * the power path will only be partially turned on. So under
+ * such situation, the IEOC is inaccurate.
+ */
+ rv = rt946x_get_ieoc(&curr_ieoc);
+ if (rv)
+ return rv;
+
+ if (current < 900 && !workaround) {
+ /* raise IEOC if charge current is under 900 */
+ rv = rt946x_set_ieoc(curr_ieoc + 100);
+ workaround = 1;
+ } else if (current >= 900 && workaround) {
+ /* reset IEOC if charge current is above 900 */
+ workaround = 0;
+ rv = rt946x_set_ieoc(curr_ieoc - 100);
+ }
+ }
- return rt946x_update_bits(RT946X_REG_CHGCTRL7, RT946X_MASK_ICHG,
- reg_icc << RT946X_SHIFT_ICHG);
+ return rv;
}
int charger_get_voltage(int *voltage)