diff options
Diffstat (limited to 'zephyr/program/corsola/src/krabby/charger_workaround.c')
-rw-r--r-- | zephyr/program/corsola/src/krabby/charger_workaround.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/zephyr/program/corsola/src/krabby/charger_workaround.c b/zephyr/program/corsola/src/krabby/charger_workaround.c new file mode 100644 index 0000000000..be046a947b --- /dev/null +++ b/zephyr/program/corsola/src/krabby/charger_workaround.c @@ -0,0 +1,93 @@ +/* Copyright 2022 The ChromiumOS Authors + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "charger.h" +#include "driver/charger/rt9490.h" +#include "hooks.h" +#include "i2c.h" +#include "system.h" + +#include <zephyr/sys/util.h> + +/* + * This workaround and the board id checks only apply to krabby and early + * tentacruel devices. + * Newer project should have all of these fixed. + */ +BUILD_ASSERT(IS_ENABLED(CONFIG_BOARD_KRABBY) || + IS_ENABLED(CONFIG_BOARD_TENTACRUEL) || IS_ENABLED(CONFIG_TEST)); + +/* b/194967754#comment5: work around for IBUS ADC unstable issue */ +static void ibus_adc_workaround(void) +{ + if (system_get_board_version() != 0) { + return; + } + + i2c_update8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, + RT9490_REG_ADC_CHANNEL0, RT9490_VSYS_ADC_DIS, MASK_SET); + + rt9490_enable_hidden_mode(CHARGER_SOLO, true); + /* undocumented registers... */ + i2c_write8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, 0x52, 0xC4); + + i2c_update8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, + RT9490_REG_ADC_CHANNEL0, RT9490_VSYS_ADC_DIS, MASK_CLR); + rt9490_enable_hidden_mode(CHARGER_SOLO, false); +} + +/* b/214880220#comment44: lock i2c at 400khz */ +static void i2c_speed_workaround(void) +{ + if (system_get_board_version() >= 3) { + return; + } + + rt9490_enable_hidden_mode(CHARGER_SOLO, true); + /* Set to Auto mode, default run at 400kHz */ + i2c_write8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, 0x71, 0x22); + /* Manually select for 400kHz, valid only when 0x71[7] == 1 */ + i2c_write8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, 0xF7, 0x14); + rt9490_enable_hidden_mode(CHARGER_SOLO, false); +} + +static void eoc_deglitch_workaround(void) +{ + if (system_get_board_version() != 1) { + return; + } + + /* set end-of-charge deglitch time to 2ms */ + i2c_update8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, + RT9490_REG_ADD_CTRL0, RT9490_TD_EOC, MASK_CLR); +} + +static void disable_safety_timer(void) +{ + if (system_get_board_version() >= 2) { + return; + } + /* Disable charge timer */ + i2c_write8(chg_chips[CHARGER_SOLO].i2c_port, + chg_chips[CHARGER_SOLO].i2c_addr_flags, + RT9490_REG_SAFETY_TMR_CTRL, + RT9490_EN_TRICHG_TMR | RT9490_EN_PRECHG_TMR | + RT9490_EN_FASTCHG_TMR); +} + +static void board_rt9490_workaround(void) +{ + ibus_adc_workaround(); + i2c_speed_workaround(); + eoc_deglitch_workaround(); + disable_safety_timer(); +} +DECLARE_HOOK(HOOK_INIT, board_rt9490_workaround, HOOK_PRIO_DEFAULT); |