summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/drawcia/board.c16
-rw-r--r--board/waddledee/board.c16
-rw-r--r--driver/charger/sm5803.c117
-rw-r--r--driver/charger/sm5803.h4
4 files changed, 153 insertions, 0 deletions
diff --git a/board/drawcia/board.c b/board/drawcia/board.c
index 3adcbb819a..1b872683fa 100644
--- a/board/drawcia/board.c
+++ b/board/drawcia/board.c
@@ -424,6 +424,22 @@ void board_init(void)
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+static void board_resume(void)
+{
+ sm5803_disable_low_power_mode(CHARGER_PRIMARY);
+ if (board_get_charger_chip_count() > 1)
+ sm5803_disable_low_power_mode(CHARGER_SECONDARY);
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_resume, HOOK_PRIO_DEFAULT);
+
+static void board_suspend(void)
+{
+ sm5803_enable_low_power_mode(CHARGER_PRIMARY);
+ if (board_get_charger_chip_count() > 1)
+ sm5803_enable_low_power_mode(CHARGER_SECONDARY);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_suspend, HOOK_PRIO_DEFAULT);
+
void board_hibernate(void)
{
/*
diff --git a/board/waddledee/board.c b/board/waddledee/board.c
index 96f0b8841c..9a4b8432cc 100644
--- a/board/waddledee/board.c
+++ b/board/waddledee/board.c
@@ -270,6 +270,22 @@ void board_init(void)
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
+static void board_resume(void)
+{
+ sm5803_disable_low_power_mode(CHARGER_PRIMARY);
+ if (board_get_charger_chip_count() > 1)
+ sm5803_disable_low_power_mode(CHARGER_SECONDARY);
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, board_resume, HOOK_PRIO_DEFAULT);
+
+static void board_suspend(void)
+{
+ sm5803_enable_low_power_mode(CHARGER_PRIMARY);
+ if (board_get_charger_chip_count() > 1)
+ sm5803_enable_low_power_mode(CHARGER_SECONDARY);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, board_suspend, HOOK_PRIO_DEFAULT);
+
void board_hibernate(void)
{
/*
diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c
index 30f9826ff6..207404f96f 100644
--- a/driver/charger/sm5803.c
+++ b/driver/charger/sm5803.c
@@ -702,6 +702,123 @@ void sm5803_hibernate(int chgnum)
CPRINTS("%s %d: Failed to set hibernate", CHARGER_NAME, chgnum);
}
+static void sm5803_disable_runtime_low_power_mode(void)
+{
+ enum ec_error_list rv;
+ int reg;
+ int chgnum = TASK_ID_TO_PD_PORT(task_get_current());
+
+ CPRINTS("%s %d: disable runtime low power mode", CHARGER_NAME, chgnum);
+ rv = main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
+ if (rv) {
+ CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME,
+ chgnum);
+ return;
+ }
+ /* Set a higher clock speed */
+ rv |= main_read8(chgnum, SM5803_REG_CLOCK_SEL, &reg);
+ reg &= ~SM5803_CLOCK_SEL_LOW;
+ rv |= main_write8(chgnum, SM5803_REG_CLOCK_SEL, reg);
+
+ /* Enable ADC sigma delta */
+ rv |= chg_read8(chgnum, SM5803_REG_CC_CONFIG1, &reg);
+ reg |= SM5803_CC_CONFIG1_SD_PWRUP;
+ rv |= chg_write8(chgnum, SM5803_REG_CC_CONFIG1, reg);
+
+ if (rv)
+ CPRINTS("%s %d: Failed to set in disable runtime LPM",
+ CHARGER_NAME, chgnum);
+}
+DECLARE_HOOK(HOOK_USB_PD_CONNECT,
+ sm5803_disable_runtime_low_power_mode,
+ HOOK_PRIO_FIRST);
+
+static void sm5803_enable_runtime_low_power_mode(void)
+{
+ enum ec_error_list rv;
+ int reg;
+ int chgnum = TASK_ID_TO_PD_PORT(task_get_current());
+
+ CPRINTS("%s %d: enable runtime low power mode", CHARGER_NAME, chgnum);
+ rv = main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
+ if (rv) {
+ CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME,
+ chgnum);
+ return;
+ }
+ /* Slow the clock speed */
+ rv |= main_read8(chgnum, SM5803_REG_CLOCK_SEL, &reg);
+ reg |= SM5803_CLOCK_SEL_LOW;
+ rv |= main_write8(chgnum, SM5803_REG_CLOCK_SEL, reg);
+
+ /* Disable ADC sigma delta */
+ rv |= chg_read8(chgnum, SM5803_REG_CC_CONFIG1, &reg);
+ reg &= ~SM5803_CC_CONFIG1_SD_PWRUP;
+ rv |= chg_write8(chgnum, SM5803_REG_CC_CONFIG1, reg);
+
+ if (rv)
+ CPRINTS("%s %d: Failed to set in enable runtime LPM",
+ CHARGER_NAME, chgnum);
+}
+DECLARE_HOOK(HOOK_USB_PD_DISCONNECT,
+ sm5803_enable_runtime_low_power_mode,
+ HOOK_PRIO_LAST);
+
+void sm5803_disable_low_power_mode(int chgnum)
+{
+ enum ec_error_list rv;
+ int reg;
+
+ CPRINTS("%s %d: disable low power mode", CHARGER_NAME, chgnum);
+ rv = main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
+ if (rv) {
+ CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME,
+ chgnum);
+ return;
+ }
+ /* Enable Psys DAC */
+ rv |= meas_read8(chgnum, SM5803_REG_PSYS1, &reg);
+ reg |= SM5803_PSYS1_DAC_EN;
+ rv |= meas_write8(chgnum, SM5803_REG_PSYS1, reg);
+
+ /* Enable PROCHOT comparators except Ibus */
+ rv |= chg_read8(chgnum, SM5803_REG_PHOT1, &reg);
+ reg |= SM5803_PHOT1_COMPARATOR_EN;
+ reg &= ~SM5803_PHOT1_IBUS_PHOT_COMP_EN;
+ rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);
+
+ if (rv)
+ CPRINTS("%s %d: Failed to set in disable low power mode",
+ CHARGER_NAME, chgnum);
+}
+
+void sm5803_enable_low_power_mode(int chgnum)
+{
+ enum ec_error_list rv;
+ int reg;
+
+ CPRINTS("%s %d: enable low power mode", CHARGER_NAME, chgnum);
+ rv = main_read8(chgnum, SM5803_REG_REFERENCE, &reg);
+ if (rv) {
+ CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME,
+ chgnum);
+ return;
+ }
+ /* Disable Psys DAC */
+ rv |= meas_read8(chgnum, SM5803_REG_PSYS1, &reg);
+ reg &= ~SM5803_PSYS1_DAC_EN;
+ rv |= meas_write8(chgnum, SM5803_REG_PSYS1, reg);
+
+ /* Disable PROCHOT comparators */
+ rv |= chg_read8(chgnum, SM5803_REG_PHOT1, &reg);
+ reg &= ~SM5803_PHOT1_COMPARATOR_EN;
+ rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);
+
+ if (rv)
+ CPRINTS("%s %d: Failed to set in enable low power mode",
+ CHARGER_NAME, chgnum);
+}
+
/*
* Process interrupt registers and report any Vbus changes. Alert the AP if the
* charger has become too hot.
diff --git a/driver/charger/sm5803.h b/driver/charger/sm5803.h
index fe71314b1a..93cf9a462d 100644
--- a/driver/charger/sm5803.h
+++ b/driver/charger/sm5803.h
@@ -335,6 +335,10 @@ enum ec_error_list sm5803_vbus_sink_enable(int chgnum, int enable);
void sm5803_hibernate(int chgnum);
void sm5803_interrupt(int chgnum);
+/* Expose low power mode functions */
+void sm5803_disable_low_power_mode(int chgnum);
+void sm5803_enable_low_power_mode(int chgnum);
+
extern const struct charger_drv sm5803_drv;
#endif