diff options
-rw-r--r-- | board/drawcia/board.c | 11 | ||||
-rw-r--r-- | board/waddledee/board.c | 11 | ||||
-rw-r--r-- | driver/charger/sm5803.c | 74 | ||||
-rw-r--r-- | driver/charger/sm5803.h | 13 |
4 files changed, 107 insertions, 2 deletions
diff --git a/board/drawcia/board.c b/board/drawcia/board.c index 4a012aafa8..3adcbb819a 100644 --- a/board/drawcia/board.c +++ b/board/drawcia/board.c @@ -424,6 +424,17 @@ void board_init(void) } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); +void board_hibernate(void) +{ + /* + * Put all charger ICs present into low power mode before entering + * z-state. + */ + sm5803_hibernate(CHARGER_PRIMARY); + if (board_get_charger_chip_count() > 1) + sm5803_hibernate(CHARGER_SECONDARY); +} + __override void board_ocpc_init(struct ocpc_data *ocpc) { /* There's no provision to measure Isys */ diff --git a/board/waddledee/board.c b/board/waddledee/board.c index 91a99272c7..96f0b8841c 100644 --- a/board/waddledee/board.c +++ b/board/waddledee/board.c @@ -270,6 +270,17 @@ void board_init(void) } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); +void board_hibernate(void) +{ + /* + * Put all charger ICs present into low power mode before entering + * z-state. + */ + sm5803_hibernate(CHARGER_PRIMARY); + if (board_get_charger_chip_count() > 1) + sm5803_hibernate(CHARGER_SECONDARY); +} + __override void board_ocpc_init(struct ocpc_data *ocpc) { /* There's no provision to measure Isys */ diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c index 85bd9ce081..30f9826ff6 100644 --- a/driver/charger/sm5803.c +++ b/driver/charger/sm5803.c @@ -527,8 +527,32 @@ static void sm5803_init(int chgnum) rv |= main_write8(chgnum, 0x1F, 0x0); } - /* Disable Ibus PROCHOT comparator */ - rv = chg_read8(chgnum, SM5803_REG_PHOT1, ®); + /* Enable LDO bits */ + rv |= main_read8(chgnum, SM5803_REG_REFERENCE, ®); + reg &= ~(BIT(0) | BIT(1)); + rv |= main_write8(chgnum, SM5803_REG_REFERENCE, reg); + + /* Set a higher clock speed in case it was lowered for z-state */ + rv |= main_read8(chgnum, SM5803_REG_CLOCK_SEL, ®); + reg &= ~SM5803_CLOCK_SEL_LOW; + rv |= main_write8(chgnum, SM5803_REG_CLOCK_SEL, reg); + + /* Turn on GPADCs to default */ + rv |= meas_write8(chgnum, SM5803_REG_GPADC_CONFIG1, 0xF3); + + /* Enable Psys DAC */ + rv |= meas_read8(chgnum, SM5803_REG_PSYS1, ®); + reg |= SM5803_PSYS1_DAC_EN; + rv |= meas_write8(chgnum, SM5803_REG_PSYS1, reg); + + /* Enable ADC sigma delta */ + rv |= chg_read8(chgnum, SM5803_REG_CC_CONFIG1, ®); + reg |= SM5803_CC_CONFIG1_SD_PWRUP; + rv |= chg_write8(chgnum, SM5803_REG_CC_CONFIG1, reg); + + /* Enable PROCHOT comparators except Ibus */ + rv |= chg_read8(chgnum, SM5803_REG_PHOT1, ®); + reg |= SM5803_PHOT1_COMPARATOR_EN; reg &= ~SM5803_PHOT1_IBUS_PHOT_COMP_EN; rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg); @@ -632,6 +656,52 @@ static enum ec_error_list sm5803_post_init(int chgnum) return EC_SUCCESS; } +void sm5803_hibernate(int chgnum) +{ + enum ec_error_list rv; + int reg; + + rv = main_read8(chgnum, SM5803_REG_REFERENCE, ®); + if (rv) { + CPRINTS("%s %d: Failed to read REFERENCE reg", CHARGER_NAME, + chgnum); + return; + } + + /* Disable LDO bits - note the primary LDO should not be disabled */ + if (chgnum != CHARGER_PRIMARY) { + reg |= (BIT(0) | BIT(1)); + rv |= main_write8(chgnum, SM5803_REG_REFERENCE, reg); + } + + /* Slow the clock speed */ + rv |= main_read8(chgnum, SM5803_REG_CLOCK_SEL, ®); + reg |= SM5803_CLOCK_SEL_LOW; + rv |= main_write8(chgnum, SM5803_REG_CLOCK_SEL, reg); + + /* Turn off GPADCs */ + rv |= meas_write8(chgnum, SM5803_REG_GPADC_CONFIG1, 0); + rv |= meas_write8(chgnum, SM5803_REG_GPADC_CONFIG2, 0); + + /* Disable Psys DAC */ + rv |= meas_read8(chgnum, SM5803_REG_PSYS1, ®); + reg &= ~SM5803_PSYS1_DAC_EN; + rv |= meas_write8(chgnum, SM5803_REG_PSYS1, reg); + + /* Disable ADC sigma delta */ + rv |= chg_read8(chgnum, SM5803_REG_CC_CONFIG1, ®); + reg &= ~SM5803_CC_CONFIG1_SD_PWRUP; + rv |= chg_write8(chgnum, SM5803_REG_CC_CONFIG1, reg); + + /* Disable PROCHOT comparators */ + rv |= chg_read8(chgnum, SM5803_REG_PHOT1, ®); + reg &= ~SM5803_PHOT1_COMPARATOR_EN; + rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg); + + if (rv) + CPRINTS("%s %d: Failed to set hibernate", 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 7c0eaca78b..fe71314b1a 100644 --- a/driver/charger/sm5803.h +++ b/driver/charger/sm5803.h @@ -84,6 +84,9 @@ #define SM5803_REFERENCE_LDO3P3_PGOOD BIT(4) #define SM5803_REFERENCE_LDO5_PGOOD BIT(5) +#define SM5803_REG_CLOCK_SEL 0x2A +#define SM5803_CLOCK_SEL_LOW BIT(0) + #define SM5803_REG_GPIO0_CTRL 0x30 #define SM5803_GPIO0_VAL BIT(0) #define SM5803_GPIO0_MODE_MASK GENMASK(2, 1) @@ -121,6 +124,11 @@ enum sm5803_gpio0_modes { #define SM5803_GPADCC1_VSYS_EN BIT(6) /* NOTE: DO NOT CLEAR */ #define SM5803_GPADCC1_TINT_EN BIT(7) +#define SM5803_REG_GPADC_CONFIG2 0x02 + +#define SM5803_REG_PSYS1 0x04 +#define SM5803_PSYS1_DAC_EN BIT(0) + /* Note: Threshold registers all assume lower 2 bits are 0 */ #define SM5803_REG_VBUS_LOW_TH 0x1A #define SM5803_REG_VBUS_HIGH_TH 0x2A @@ -168,6 +176,9 @@ enum sm5803_gpio0_modes { /* Charger registers (address 0x32) */ +#define SM5803_REG_CC_CONFIG1 0x01 +#define SM5803_CC_CONFIG1_SD_PWRUP BIT(3) + #define SM5803_REG_FLOW1 0x1C #define SM5803_FLOW1_MODE GENMASK(1, 0) #define SM5803_FLOW1_DIRECTCHG_SRC_EN BIT(2) @@ -288,6 +299,7 @@ enum sm5803_charger_modes { #define SM5803_PHOT1_IBUS_PHOT_COMP_EN BIT(1) #define SM5803_PHOT1_VSYS_MON_EN BIT(2) #define SM5803_PHOT1_VBUS_MON_EN BIT(3) +#define SM5803_PHOT1_COMPARATOR_EN GENMASK(3, 0) #define SM5803_PHOT1_DURATION GENMASK(6, 4) #define SM5803_PHOT1_DURATION_SHIFT 4 #define SM5803_PHOT1_IRQ_MODE BIT(7) @@ -320,6 +332,7 @@ enum ec_error_list sm5803_get_chg_det(int chgnum, int *chg_det); enum ec_error_list sm5803_set_vbus_disch(int chgnum, int enable); enum ec_error_list sm5803_vbus_sink_enable(int chgnum, int enable); +void sm5803_hibernate(int chgnum); void sm5803_interrupt(int chgnum); extern const struct charger_drv sm5803_drv; |