summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYilun Lin <yllin@google.com>2018-11-14 14:29:19 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-11-19 03:26:25 -0800
commitec46635948f5073ecb608e799b738f954bfd7fbd (patch)
tree0a2bccf5e7505c339aa4c33249830b70e48e71cb
parentb4ef387f133991454ec890342f8fc651dab3c80a (diff)
downloadchrome-ec-ec46635948f5073ecb608e799b738f954bfd7fbd.tar.gz
kukui: Fix shipping mode VSYS leakage.
Follow the cut-off procedure recommended by Richtek. Also, tcpc_read/tcpc_write function will wake the TCPC up from low power mode and thus causing the TCPC re-init again, and this will break the register state we set. So, here we use mt6370_i2c_read/write to replace tcpc_read/write. TEST=boot system; Exec cutoff, and check that Vsys equals to zero. BUG=b:116682788 BRANCH=None Change-Id: I5cbd0df490ddb64b9376507e42a259c008c3ba16 Signed-off-by: Yilun Lin <yllin@google.com> Reviewed-on: https://chromium-review.googlesource.com/1335289 Commit-Ready: Yilun Lin <yllin@chromium.org> Tested-by: Yilun Lin <yllin@chromium.org> Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
-rw-r--r--board/kukui/battery.c8
-rw-r--r--driver/charger/rt946x.c26
-rw-r--r--driver/charger/rt946x.h31
-rw-r--r--driver/tcpm/mt6370.c23
-rw-r--r--driver/tcpm/mt6370.h13
5 files changed, 96 insertions, 5 deletions
diff --git a/board/kukui/battery.c b/board/kukui/battery.c
index 0c875d0032..ff5764ff97 100644
--- a/board/kukui/battery.c
+++ b/board/kukui/battery.c
@@ -11,6 +11,7 @@
#include "console.h"
#include "driver/battery/max17055.h"
#include "driver/charger/rt946x.h"
+#include "driver/tcpm/mt6370.h"
#include "ec_commands.h"
#include "extpower.h"
#include "gpio.h"
@@ -82,7 +83,12 @@ const struct max17055_alert_profile *max17055_get_alert_profile(void)
int board_cut_off_battery(void)
{
- return rt946x_cutoff_battery();
+ /* The cut-off procedure is recommended by Richtek. b/116682788 */
+ rt946x_por_reset();
+ mt6370_vconn_discharge(0);
+ rt946x_cutoff_battery();
+
+ return EC_SUCCESS;
}
enum battery_disconnect_state battery_get_disconnect_state(void)
diff --git a/driver/charger/rt946x.c b/driver/charger/rt946x.c
index 9bb1a6cfd7..c6f748017d 100644
--- a/driver/charger/rt946x.c
+++ b/driver/charger/rt946x.c
@@ -213,15 +213,28 @@ static inline int rt946x_enable_hz(int en)
(RT946X_REG_CHGCTRL1, RT946X_MASK_HZ_EN);
}
-static int rt946x_por_reset(void)
+int rt946x_por_reset(void)
{
- int rv = 0;
+ int rv, val;
+#ifdef CONFIG_CHARGER_MT6370
+ /* Soft reset. It takes only 1ns for resetting. b/116682788 */
+ val = RT946X_MASK_SOFT_RST;
+ /*
+ * MT6370 has to set passcodes before resetting all the registers and
+ * logics.
+ */
+ rv = rt946x_write8(MT6370_REG_RSTPASCODE1, MT6370_MASK_RSTPASCODE1);
+ rv |= rt946x_write8(MT6370_REG_RSTPASCODE2, MT6370_MASK_RSTPASCODE2);
+#else
+ /* Hard reset, may take several milliseconds. */
+ val = RT946X_MASK_RST;
rv = rt946x_enable_hz(0);
+#endif
if (rv)
return rv;
- return rt946x_set_bit(RT946X_REG_CORECTRL_RST, RT946X_MASK_RST);
+ return rt946x_set_bit(RT946X_REG_CORECTRL_RST, val);
}
static int rt946x_reset_to_zero(void)
@@ -967,7 +980,12 @@ int rt946x_is_charge_done(void)
int rt946x_cutoff_battery(void)
{
- return rt946x_set_bit(RT946X_REG_CHGCTRL2, RT946X_MASK_SHIP_MODE);
+ int val = RT946X_MASK_SHIP_MODE;
+
+#ifdef CONFIG_CHARGER_MT6370
+ val |= RT946X_MASK_TE | RT946X_MASK_CFO_EN | RT946X_MASK_CHG_EN;
+#endif
+ return rt946x_set_bit(RT946X_REG_CHGCTRL2, val);
}
int rt946x_enable_charge_termination(int en)
diff --git a/driver/charger/rt946x.h b/driver/charger/rt946x.h
index ff126bc079..21ce65536b 100644
--- a/driver/charger/rt946x.h
+++ b/driver/charger/rt946x.h
@@ -92,6 +92,8 @@
#define RT946X_REG_CORECTRL1 0x01
#define RT946X_REG_CORECTRL2 0x02
#define RT946X_REG_CORECTRL_RST RT946X_REG_CORECTRL2
+#define MT6370_REG_RSTPASCODE1 0x03
+#define MT6370_REG_RSTPASCODE2 0x04
#define RT946X_REG_CHGCTRL1 0x11
#define RT946X_REG_CHGCTRL2 0x12
#define RT946X_REG_CHGCTRL3 0x13
@@ -229,8 +231,26 @@
/* ========== CORECTRL0 0x00 ============ */
#define RT946X_SHIFT_RST 7
+#define RT946X_SHIFT_CHG_RST 6
+#define RT946X_SHIFT_FLED_RST 5
+#define RT946X_SHIFT_LDO_RST 4
+#define RT946X_SHIFT_RGB_RST 3
+#define RT946X_SHIFT_BL_RST 2
+#define RT946X_SHIFT_DB_RST 1
+#define RT946X_SHIFT_REG_RST 0
#define RT946X_MASK_RST (1 << RT946X_SHIFT_RST)
+#define RT946X_MASK_CHG_RST (1 << RT946X_SHIFT_CHG_RST)
+#define RT946X_MASK_FLED_RST (1 << RT946X_SHIFT_FLED_RST)
+#define RT946X_MASK_LDO_RST (1 << RT946X_SHIFT_LDO_RST)
+#define RT946X_MASK_RGB_RST (1 << RT946X_SHIFT_RGB_RST)
+#define RT946X_MASK_BL_RST (1 << RT946X_SHIFT_BL_RST)
+#define RT946X_MASK_DB_RST (1 << RT946X_SHIFT_DB_RST)
+#define RT946X_MASK_REG_RST (1 << RT946X_SHIFT_REG_RST)
+#define RT946X_MASK_SOFT_RST \
+ (RT946X_MASK_CHG_RST | RT946X_MASK_FLED_RST | RT946X_MASK_LDO_RST | \
+ RT946X_MASK_RGB_RST | RT946X_MASK_BL_RST | RT946X_MASK_DB_RST | \
+ RT946X_MASK_REG_RST)
/* ========== CHGCTRL1 0x01 ============ */
#define RT946X_SHIFT_OPA_MODE 0
@@ -243,13 +263,18 @@
#define RT946X_SHIFT_SHIP_MODE 7
#define RT946X_SHIFT_TE 4
#define RT946X_SHIFT_ILMTSEL 2
+#define RT946X_SHIFT_CFO_EN 1
#define RT946X_SHIFT_CHG_EN 0
#define RT946X_MASK_SHIP_MODE (1 << RT946X_SHIFT_SHIP_MODE)
#define RT946X_MASK_TE (1 << RT946X_SHIFT_TE)
#define RT946X_MASK_ILMTSEL (0x3 << RT946X_SHIFT_ILMTSEL)
+#define RT946X_MASK_CFO_EN (1 << RT946X_SHIFT_CFO_EN)
#define RT946X_MASK_CHG_EN (1 << RT946X_SHIFT_CHG_EN)
+/* ========== RSTPASCODE1 0x03 (mt6370) ============ */
+#define MT6370_MASK_RSTPASCODE1 0xA9
+
/* ========== CHGCTRL3 0x03 ============ */
#define RT946X_SHIFT_AICR 2
#define RT946X_SHIFT_ILIMEN 0
@@ -257,6 +282,9 @@
#define RT946X_MASK_AICR (0x3F << RT946X_SHIFT_AICR)
#define RT946X_MASK_ILIMEN (1 << RT946X_SHIFT_ILIMEN)
+/* ========== RSTPASCODE2 0x04 (mt6370) ============ */
+#define MT6370_MASK_RSTPASCODE2 0x96
+
/* ========== CHGCTRL4 0x04 ============ */
#define RT946X_SHIFT_CV 1
@@ -475,6 +503,9 @@
/* RT946x specific interface functions */
+/* Power on reset */
+int rt946x_por_reset(void);
+
/* Interrupt handler for rt946x */
void rt946x_interrupt(enum gpio_signal signal);
diff --git a/driver/tcpm/mt6370.c b/driver/tcpm/mt6370.c
index a77dd96b57..dba3a045a0 100644
--- a/driver/tcpm/mt6370.c
+++ b/driver/tcpm/mt6370.c
@@ -19,6 +19,13 @@
#define CPRINTS(format, args...) cprints(CC_USBCHARGE, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_USBCHARGE, format, ## args)
+/* i2c_write function which won't wake TCPC from low power mode. */
+static int mt6370_i2c_write8(int port, int reg, int val)
+{
+ return i2c_write8(tcpc_config[port].i2c_host_port,
+ tcpc_config[port].i2c_slave_addr, reg, val);
+}
+
static int mt6370_init(int port)
{
int rv;
@@ -118,6 +125,22 @@ static int mt6370_enter_low_power_mode(int port)
}
#endif
+int mt6370_vconn_discharge(int port)
+{
+ /*
+ * Write to mt6370 in low-power mode may return fail, but it is
+ * actually written. So we just ignore its return value.
+ */
+ mt6370_i2c_write8(port, MT6370_REG_OVP_FLAG_SEL,
+ MT6370_REG_DISCHARGE_LVL);
+ /* Set MT6370_REG_DISCHARGE_EN bit and also the rest default value. */
+ mt6370_i2c_write8(port, MT6370_REG_BMC_CTRL,
+ MT6370_REG_DISCHARGE_EN |
+ MT6370_REG_BMC_CTRL_DEFAULT);
+
+ return EC_SUCCESS;
+}
+
/* MT6370 is a TCPCI compatible port controller */
const struct tcpm_drv mt6370_tcpm_drv = {
.init = &mt6370_init,
diff --git a/driver/tcpm/mt6370.h b/driver/tcpm/mt6370.h
index ff9ac569ee..5fdcffbdca 100644
--- a/driver/tcpm/mt6370.h
+++ b/driver/tcpm/mt6370.h
@@ -102,6 +102,16 @@
#define MT6370_REG_BMCIO_BG_EN (1 << 2)
#define MT6370_REG_VBUS_DET_EN (1 << 1)
#define MT6370_REG_BMCIO_OSC_EN (1 << 0)
+#define MT6370_REG_BMC_CTRL_DEFAULT \
+ (MT6370_REG_BMCIO_BG_EN | MT6370_REG_VBUS_DET_EN | \
+ MT6370_REG_BMCIO_OSC_EN)
+
+/*
+ * MT6370_REG_OVP_FLAG_SEL
+ */
+
+#define MT6370_MASK_DISCHARGE_LVL 0x03
+#define MT6370_REG_DISCHARGE_LVL (1 << 0)
/*
* MT6370_REG_RT_STATUS 0x97
@@ -176,4 +186,7 @@
extern const struct tcpm_drv mt6370_tcpm_drv;
+/* Enable VCONN discharge. */
+int mt6370_vconn_discharge(int port);
+
#endif /* __CROS_EC_USB_PD_TCPM_MT6370_H */