diff options
-rw-r--r-- | board/eldrid/board.c | 58 | ||||
-rw-r--r-- | driver/charger/isl9241.c | 35 | ||||
-rw-r--r-- | driver/charger/isl9241.h | 19 |
3 files changed, 111 insertions, 1 deletions
diff --git a/board/eldrid/board.c b/board/eldrid/board.c index 1ce028d96e..cf46f04edb 100644 --- a/board/eldrid/board.c +++ b/board/eldrid/board.c @@ -24,6 +24,7 @@ #include "fan_chip.h" #include "gpio.h" #include "hooks.h" +#include "isl9241.h" #include "keyboard_8042_sharedlib.h" #include "keyboard_raw.h" #include "lid_switch.h" @@ -73,10 +74,58 @@ union volteer_cbi_fw_config fw_config_defaults = { .usb_db = DB_USB3_ACTIVE, }; +static void board_charger_config(void) +{ + /* + * b/166728543, we configured charger setting to throttle CPU + * when the system loading is at battery current limit. + */ + int reg; + + /* + * Set DCProchot# to 5120mA + */ + isl9241_set_dc_prochot(CHARGER_SOLO, 5120); + + /* + * Set Control1 bit<3> = 1, PSYS = 1 + */ + if (i2c_read16(I2C_PORT_CHARGER, ISL9241_ADDR_FLAGS, + ISL9241_REG_CONTROL1, ®) == EC_SUCCESS) { + reg |= ISL9241_CONTROL1_PSYS; + if (i2c_write16(I2C_PORT_CHARGER, ISL9241_ADDR_FLAGS, + ISL9241_REG_CONTROL1, reg)) + CPRINTS("Failed to set isl9241"); + } + + /* + * Set Control2 bit<10:9> = 00, PROCHOT# Debounce = 7us + */ + if (i2c_read16(I2C_PORT_CHARGER, ISL9241_ADDR_FLAGS, + ISL9241_REG_CONTROL2, ®) == EC_SUCCESS) { + reg &= ~ISL9241_CONTROL2_PROCHOT_DEBOUNCE_MASK; + if (i2c_write16(I2C_PORT_CHARGER, ISL9241_ADDR_FLAGS, + ISL9241_REG_CONTROL2, reg)) + CPRINTS("Failed to set isl9241"); + } + + /* + * Set Control4 bit<11> = 1, PSYS Rsense Ratio = 1:1 + */ + if (i2c_read16(I2C_PORT_CHARGER, ISL9241_ADDR_FLAGS, + ISL9241_REG_CONTROL4, ®) == EC_SUCCESS) { + reg |= ISL9241_CONTROL4_PSYS_RSENSE_RATIO; + if (i2c_write16(I2C_PORT_CHARGER, ISL9241_ADDR_FLAGS, + ISL9241_REG_CONTROL4, reg)) + CPRINTS("Failed to set isl9241"); + } +} + static void board_init(void) { pwm_enable(PWM_CH_LED4_SIDESEL, 1); pwm_set_duty(PWM_CH_LED4_SIDESEL, 100); + board_charger_config(); } DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT); @@ -125,6 +174,15 @@ __override void board_set_charge_limit(int port, int supplier, int charge_ma, int max_ma, int charge_mv) { /* + * b/166728543 + * Set different AC_PROCHOT value when using different wattage ADT. + */ + if (max_ma * charge_mv == PD_MAX_POWER_MW * 1000) + isl9241_set_ac_prochot(0, 3072); + else + isl9241_set_ac_prochot(0, 2816); + + /* * Follow OEM request to limit the input current to * 90% negotiated limit when S0. */ diff --git a/driver/charger/isl9241.c b/driver/charger/isl9241.c index 626c84fe07..4fd92e6c08 100644 --- a/driver/charger/isl9241.c +++ b/driver/charger/isl9241.c @@ -323,7 +323,19 @@ static enum ec_error_list isl9241_discharge_on_ac(int chgnum, int enable) int isl9241_set_ac_prochot(int chgnum, int ma) { int rv; - uint16_t reg = AC_CURRENT_TO_REG(ma); + uint16_t reg; + + /* + * The register reserves bits [6:0] and bits [15:13]. + * This routine should ensure these bits are not set + * before writing the register. + */ + if (ma > AC_REG_TO_CURRENT(ISL9241_AC_PROCHOT_CURRENT_MAX)) + reg = ISL9241_AC_PROCHOT_CURRENT_MAX; + else if (ma < AC_REG_TO_CURRENT(ISL9241_AC_PROCHOT_CURRENT_MIN)) + reg = ISL9241_AC_PROCHOT_CURRENT_MIN; + else + reg = AC_CURRENT_TO_REG(ma); rv = isl9241_write(chgnum, ISL9241_REG_AC_PROCHOT, reg); if (rv) @@ -332,6 +344,27 @@ int isl9241_set_ac_prochot(int chgnum, int ma) return rv; } +int isl9241_set_dc_prochot(int chgnum, int ma) +{ + int rv; + + /* + * The register reserves bits [7:0] and bits [15:14]. + * This routine should ensure these bits are not set + * before writing the register. + */ + if (ma > ISL9241_DC_PROCHOT_CURRENT_MAX) + ma = ISL9241_DC_PROCHOT_CURRENT_MAX; + else if (ma < ISL9241_DC_PROCHOT_CURRENT_MIN) + ma = ISL9241_DC_PROCHOT_CURRENT_MIN; + + rv = isl9241_write(chgnum, ISL9241_REG_DC_PROCHOT, ma); + if (rv) + CPRINTF("set_dc_prochot failed (%d)\n", rv); + + return rv; +} + /*****************************************************************************/ /* ISL-9241 initialization */ static void isl9241_init(int chgnum) diff --git a/driver/charger/isl9241.h b/driver/charger/isl9241.h index b29a300fb2..0717a6237d 100644 --- a/driver/charger/isl9241.h +++ b/driver/charger/isl9241.h @@ -48,6 +48,7 @@ /* Configures various charger options */ #define ISL9241_REG_CONTROL1 0x3C +#define ISL9241_CONTROL1_PSYS BIT(3) #define ISL9241_CONTROL1_LEARN_MODE BIT(12) /* Configures various charger options */ @@ -67,6 +68,8 @@ /* 12 - Two-Level Adapter Current Limit */ #define ISL9241_CONTROL2_TWO_LEVEL_ADP_CURR BIT(12) /* 10:9 PROCHOT# debounce time in uS */ +#define ISL9241_CONTROL2_PROCHOT_DEBOUNCE_MASK GENMASK(10, 9) +#define ISL9241_CONTROL2_PROCHOT_DEBOUNCE_500 (2 << 9) #define ISL9241_CONTROL2_PROCHOT_DEBOUNCE_1000 (3 << 9) /* MinSystemVoltage [13:6] 8-bit (0x0000h = disables all battery charging) */ @@ -100,6 +103,8 @@ #define ISL9241_INFORMATION2_ACOK_PIN BIT(14) #define ISL9241_REG_CONTROL4 0x4E +/* 11: Rsense (Rs1:Rs2) ratio for PSYS (0 - 2:1, 1 - 1:1) */ +#define ISL9241_CONTROL4_PSYS_RSENSE_RATIO BIT(11) /* 13: Enable VSYS slew rate control (0 - disable, 1 - enable) */ #define ISL9241_CONTROL4_SLEW_RATE_CTRL BIT(13) @@ -134,4 +139,18 @@ extern const struct charger_drv isl9241_drv; */ int isl9241_set_ac_prochot(int chgnum, int ma); +/** + * Set DC prochot threshold + * + * @param chgnum: Index into charger chips + * @param ma: DC prochot threshold current in mA, multiple of 256mA + * @return EC_SUCCESS or error + */ +int isl9241_set_dc_prochot(int chgnum, int ma); + +#define ISL9241_AC_PROCHOT_CURRENT_MIN 128 /* mA */ +#define ISL9241_AC_PROCHOT_CURRENT_MAX 6400 /* mA */ +#define ISL9241_DC_PROCHOT_CURRENT_MIN 256 /* mA */ +#define ISL9241_DC_PROCHOT_CURRENT_MAX 12800 /* mA */ + #endif /* __CROS_EC_ISL9241_H */ |