From 153afcb289a02c3d794fefd02ef5819d3a9fa669 Mon Sep 17 00:00:00 2001 From: Aseda Aboagye Date: Fri, 10 Jan 2020 08:23:11 -0800 Subject: charger: Add support for RAA489000 The RAA489000 is a narrow voltage direct charging buck boost charger with an integrated USB Type-C Port Controller. The charger IC portion is very similar to the existing Intersil 923x chargers therefore, support for the RAA489000 is being added to that existing driver. BUG=b:147316511 BRANCH=None TEST=Enable on waddledoo, flash and verify that we can talk to the charger. TEST=With other patches, verify that DUT can charge a battery. Change-Id: I7788eb67f0181dd540e20db862a1ab5788f2099c Signed-off-by: Aseda Aboagye Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1995440 Tested-by: Aseda Aboagye Reviewed-by: Diana Z Reviewed-by: Daisuke Nojiri Commit-Queue: Aseda Aboagye --- driver/build.mk | 1 + driver/charger/isl923x.c | 206 ++++++++++++++++++++++++++++++----------------- driver/charger/isl923x.h | 32 +++++++- include/config.h | 3 +- 4 files changed, 166 insertions(+), 76 deletions(-) diff --git a/driver/build.mk b/driver/build.mk index ff85523bf1..64b4b98339 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -71,6 +71,7 @@ driver-$(CONFIG_CHARGER_ISL9237)+=charger/isl923x.o driver-$(CONFIG_CHARGER_ISL9238)+=charger/isl923x.o driver-$(CONFIG_CHARGER_ISL9241)+=charger/isl9241.o driver-$(CONFIG_CHARGER_MT6370)+=charger/rt946x.o +driver-$(CONFIG_CHARGER_RAA489000)+=charger/isl923x.o driver-$(CONFIG_CHARGER_RT9466)+=charger/rt946x.o driver-$(CONFIG_CHARGER_RT9467)+=charger/rt946x.o driver-$(CONFIG_CHARGER_SY21612)+=charger/sy21612.o diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c index 7a02f62ca0..716dad71ac 100644 --- a/driver/charger/isl923x.c +++ b/driver/charger/isl923x.c @@ -9,6 +9,7 @@ #include "battery.h" #include "battery_smart.h" #include "charger.h" +#include "compile_time_macros.h" #include "console.h" #include "common.h" #include "hooks.h" @@ -17,6 +18,7 @@ #include "system.h" #include "task.h" #include "timer.h" +#include "usb_pd_tcpm.h" #include "util.h" #ifndef CONFIG_CHARGER_NARROW_VDC @@ -308,13 +310,13 @@ int isl923x_set_ac_prochot(uint16_t ma) int rv; if (ma > ISL923X_AC_PROCHOT_CURRENT_MAX) { - CPRINTS("%s: invalid current (%d mA)\n", __func__, ma); + CPRINTS("%s: invalid current (%d mA)", CHARGER_NAME, ma); return EC_ERROR_INVAL; } rv = raw_write16(ISL923X_REG_PROCHOT_AC, ma); if (rv) - CPRINTS("%s failed (%d)", __func__, rv); + CPRINTS("%s set_ac_prochot failed (%d)", CHARGER_NAME, rv); return rv; } @@ -323,28 +325,43 @@ int isl923x_set_dc_prochot(uint16_t ma) int rv; if (ma > ISL923X_DC_PROCHOT_CURRENT_MAX) { - CPRINTS("%s: invalid current (%d mA)\n", __func__, ma); + CPRINTS("%s: invalid current (%d mA)", CHARGER_NAME, ma); return EC_ERROR_INVAL; } rv = raw_write16(ISL923X_REG_PROCHOT_DC, ma); if (rv) - CPRINTS("%s failed (%d)", __func__, rv); + CPRINTS("%s set_dc_prochot failed (%d)", CHARGER_NAME, rv); return rv; } static void isl923x_init(void) { int reg; - -#ifdef CONFIG_TRICKLE_CHARGING const struct battery_info *bi = battery_get_info(); int precharge_voltage = bi->precharge_voltage ? bi->precharge_voltage : bi->voltage_min; - if (raw_write16(ISL923X_REG_SYS_VOLTAGE_MIN, precharge_voltage)) - goto init_fail; -#endif + if (IS_ENABLED(CONFIG_CHARGER_RAA489000)) { + if (CONFIG_CHARGER_SENSE_RESISTOR == + CONFIG_CHARGER_SENSE_RESISTOR_AC) { + /* + * A 1:1 ratio for Rs1:Rs2 is allowed, but Control4 + * register Bit<11> must be set. + */ + if (raw_read16(ISL9238_REG_CONTROL4, ®)) + goto init_fail; + + if (raw_write16(ISL9238_REG_CONTROL4, + reg | + RAA489000_C4_PSYS_RSNS_RATIO_1_TO_1)) + goto init_fail; + } + } + + if (IS_ENABLED(CONFIG_TRICKLE_CHARGING)) + if (raw_write16(ISL923X_REG_SYS_VOLTAGE_MIN, precharge_voltage)) + goto init_fail; /* * [10:9]: Prochot# Debounce time @@ -353,80 +370,97 @@ static void isl923x_init(void) if (raw_read16(ISL923X_REG_CONTROL2, ®)) goto init_fail; + if (!IS_ENABLED(CONFIG_CHARGER_RAA489000)) + reg |= ISL923X_C2_OTG_DEBOUNCE_150; if (raw_write16(ISL923X_REG_CONTROL2, reg | - ISL923X_C2_OTG_DEBOUNCE_150 | ISL923X_C2_PROCHOT_DEBOUNCE_1000 | ISL923X_C2_ADAPTER_DEBOUNCE_150)) goto init_fail; -#ifdef CONFIG_CHARGE_RAMP_HW -#ifdef CONFIG_CHARGER_ISL9237 - if (raw_read16(ISL923X_REG_CONTROL0, ®)) - goto init_fail; - - /* Set input voltage regulation reference voltage for charge ramp */ - reg &= ~ISL9237_C0_VREG_REF_MASK; - reg |= ISL9237_C0_VREG_REF_4200; - - if (raw_write16(ISL923X_REG_CONTROL0, reg)) - goto init_fail; -#else /* !defined(CONFIG_CHARGER_ISL9237) */ - /* - * For the ISL9238, set the input voltage regulation to 4.439V. Note, - * the voltage is set in 341.3 mV steps. - */ - reg = (4439 / ISL9238_INPUT_VOLTAGE_REF_STEP) - << ISL9238_INPUT_VOLTAGE_REF_SHIFT; - - if (raw_write16(ISL9238_REG_INPUT_VOLTAGE, reg)) - goto init_fail; -#endif /* defined(CONFIG_CHARGER_ISL9237) */ -#else /* !defined(CONFIG_CHARGE_RAMP_HW) */ - if (raw_read16(ISL923X_REG_CONTROL0, ®)) - goto init_fail; - - /* Disable voltage regulation loop to disable charge ramp */ - reg |= ISL923X_C0_DISABLE_VREG; - - if (raw_write16(ISL923X_REG_CONTROL0, reg)) - goto init_fail; -#endif /* defined(CONFIG_CHARGE_RAMP_HW) */ + if (IS_ENABLED(CONFIG_CHARGE_RAMP_HW)) { + if (IS_ENABLED(CONFIG_CHARGER_ISL9237)) { + if (raw_read16(ISL923X_REG_CONTROL0, ®)) + goto init_fail; + + /* + * Set input voltage regulation reference voltage for + * charge ramp. + */ + reg &= ~ISL9237_C0_VREG_REF_MASK; + reg |= ISL9237_C0_VREG_REF_4200; + + if (raw_write16(ISL923X_REG_CONTROL0, reg)) + goto init_fail; + } else { + /* + * For the ISL9238, set the input voltage regulation to + * 4.439V. Note, the voltage is set in 341.3 mV steps. + * + * For the RAA489000, set the input voltage regulation + * to 4.437V. Note, that the voltage is set in 85.33 mV + * steps. + */ + if (IS_ENABLED(CONFIG_CHARGER_RAA489000)) + reg = (4437 / RAA489000_INPUT_VOLTAGE_REF_STEP) + << RAA489000_INPUT_VOLTAGE_REF_SHIFT; + else + reg = (4439 / ISL9238_INPUT_VOLTAGE_REF_STEP) + << ISL9238_INPUT_VOLTAGE_REF_SHIFT; + + if (raw_write16(ISL9238_REG_INPUT_VOLTAGE, reg)) + goto init_fail; + } + } else { + if (raw_read16(ISL923X_REG_CONTROL0, ®)) + goto init_fail; -#ifdef CONFIG_CHARGER_ISL9238 - /* - * Don't reread the prog pin and don't reload the ILIM on ACIN. - */ - if (raw_read16(ISL9238_REG_CONTROL3, ®)) - goto init_fail; - reg |= ISL9238_C3_NO_RELOAD_ACLIM_ON_ACIN | - ISL9238_C3_NO_REREAD_PROG_PIN; - /* - * Disable autonomous charging initially since 1) it causes boot loop - * issues with 2S batteries, and 2) it will automatically get disabled - * as soon as we manually set the current limit anyway. - */ - reg |= ISL9238_C3_DISABLE_AUTO_CHARING; - if (raw_write16(ISL9238_REG_CONTROL3, reg)) - goto init_fail; + /* Disable voltage regulation loop to disable charge ramp */ + reg |= ISL923X_C0_DISABLE_VREG; - /* - * No need to proceed with the rest of init if we sysjump'd to this - * image as the input current limit has already been set. - */ - if (system_jumped_to_this_image()) - return; + if (raw_write16(ISL923X_REG_CONTROL0, reg)) + goto init_fail; + } - /* - * Initialize the input current limit to the board's default. - */ - if (charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT)) - goto init_fail; -#endif /* defined(CONFIG_CHARGER_ISL9238) */ + if (IS_ENABLED(CONFIG_CHARGER_ISL9238) || + IS_ENABLED(CONFIG_CHARGER_RAA489000)) { + /* + * Don't reread the prog pin and don't reload the ILIM on ACIN. + * For the RAA489000, just don't reload ACLIM. + */ + if (raw_read16(ISL9238_REG_CONTROL3, ®)) + goto init_fail; + reg |= ISL9238_C3_NO_RELOAD_ACLIM_ON_ACIN; + if (!IS_ENABLED(CONFIG_CHARGER_RAA489000)) + reg |= ISL9238_C3_NO_REREAD_PROG_PIN; + + /* + * Disable autonomous charging initially since 1) it causes boot + * loop issues with 2S batteries, and 2) it will automatically + * get disabled as soon as we manually set the current limit + * anyway. + */ + reg |= ISL9238_C3_DISABLE_AUTO_CHARING; + if (raw_write16(ISL9238_REG_CONTROL3, reg)) + goto init_fail; + + /* + * No need to proceed with the rest of init if we sysjump'd to + * this image as the input current limit has already been set. + */ + if (system_jumped_to_this_image()) + return; + + /* + * Initialize the input current limit to the board's default. + */ + if (charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT)) + goto init_fail; + } return; init_fail: - CPRINTS("%s failed!", __func__); + CPRINTS("%s init failed!", CHARGER_NAME); } DECLARE_HOOK(HOOK_INIT, isl923x_init, HOOK_PRIO_INIT_I2C + 1); @@ -729,9 +763,9 @@ static int command_isl923x_dump(int argc, char **argv) dump_reg_range(0x14, 0x15); dump_reg_range(0x38, 0x3F); dump_reg_range(0x47, 0x4A); -#ifdef CONFIG_CHARGER_ISL9238 +#if defined(CONFIG_CHARGER_ISL9238) || defined(CONFIG_CHARGER_RAA489000) dump_reg_range(0x4B, 0x4E); -#endif /* CONFIG_CHARGER_ISL9238 */ +#endif /* CONFIG_CHARGER_ISL9238 || CONFIG_CHARGER_RAA489000 */ dump_reg_range(0xFE, 0xFF); return EC_SUCCESS; @@ -739,3 +773,29 @@ static int command_isl923x_dump(int argc, char **argv) DECLARE_CONSOLE_COMMAND(charger_dump, command_isl923x_dump, "", "Dumps ISL923x registers"); #endif /* CONFIG_CMD_CHARGER_DUMP */ + +int charger_get_vbus_voltage(int port) +{ + int val; + int rv; + int i2c_port; + + /* + * TODO(b:147440290): We should have a structure for charger ICs and + * consult that instead. This hack happens to work because the charger + * IC is also the TCPC. + */ + i2c_port = tcpc_config[port].i2c_info.port; + rv = i2c_read16(i2c_port, I2C_ADDR_CHARGER_FLAGS, + RAA489000_REG_ADC_VBUS, + &val); + if (rv) + return 0; + + /* The VBUS voltage is returned in bits 13:6. The LSB is 96mV. */ + val &= GENMASK(13, 6); + val = val >> 6; + val *= 96; + + return val; +} diff --git a/driver/charger/isl923x.h b/driver/charger/isl923x.h index 8076b72e38..0f9605f2de 100644 --- a/driver/charger/isl923x.h +++ b/driver/charger/isl923x.h @@ -3,6 +3,7 @@ * found in the LICENSE file. * * Intersil ISL-9237/8 battery charger driver. + * Also supports Renesas RAA489000 battery charger. */ #ifndef __CROS_EC_ISL923X_H @@ -38,6 +39,7 @@ /* Maximum charging current register value */ #define ISL923X_CURRENT_REG_MAX 0x17c0 /* bit<12:2> 10111110000 */ +#define RAA489000_CURRENT_REG_MAX 0x1ffc /* 2-level adpater current limit duration T1 & T2 in micro seconds */ #define ISL923X_T1_10000 0x00 @@ -60,6 +62,8 @@ #define ISL9237_SYS_VOLTAGE_REG_MAX 13824 #define ISL9238_SYS_VOLTAGE_REG_MAX 18304 #define ISL923X_SYS_VOLTAGE_REG_MIN 2048 +#define RAA489000_SYS_VOLTAGE_REG_MAX 18304 +#define RAA489000_SYS_VOLTAGE_REG_MIN 64 /* PROCHOT# debounce time and duration time in micro seconds */ #define ISL923X_PROCHOT_DURATION_10000 (0 << 6) @@ -201,6 +205,9 @@ /* Control2: PSYS gain in uA/W (ISL9237 only) */ #define ISL9237_C2_PSYS_GAIN BIT(0) +/* Control3: Enable ADC for all modes */ +#define RAA489000_ENABLE_ADC BIT(0) + /* * Control3: Buck-Boost switching period * 0: x1 frequency, 1: half frequency. @@ -230,6 +237,9 @@ /* Control3: Don't reread PROG pin. */ #define ISL9238_C3_NO_REREAD_PROG_PIN BIT(15) +/* Control4: PSYS Rsense ratio. */ +#define RAA489000_C4_PSYS_RSNS_RATIO_1_TO_1 BIT(11) + /* OTG voltage limit in mV, current limit in mA */ #define ISL9237_OTG_VOLTAGE_MIN 4864 #define ISL9237_OTG_VOLTAGE_MAX 5376 @@ -244,6 +254,8 @@ /* Input voltage regulation voltage reference */ #define ISL9238_INPUT_VOLTAGE_REF_STEP 341 #define ISL9238_INPUT_VOLTAGE_REF_SHIFT 8 +#define RAA489000_INPUT_VOLTAGE_REF_STEP 85 +#define RAA489000_INPUT_VOLTAGE_REF_SHIFT 6 /* Info register fields */ #define ISL9237_INFO_PROG_RESISTOR_MASK 0xf @@ -251,6 +263,9 @@ #define ISL9237_INFO_PSTATE_SHIFT 5 #define ISL9237_INFO_PSTATE_MASK 3 +/* ADC registers */ +#define RAA489000_REG_ADC_VBUS 0x88 + enum isl9237_power_stage { BUCK_MODE, BOOST_MODE, @@ -286,13 +301,26 @@ enum isl9237_fsm_state { #define CHARGE_V_MAX ISL9238_SYS_VOLTAGE_REG_MAX #define CHARGE_V_MIN ISL923X_SYS_VOLTAGE_REG_MIN #define CHARGE_V_STEP 8 +#elif defined(CONFIG_CHARGER_RAA489000) +#define CHARGER_NAME "raa489000" +#define CHARGE_V_MAX RAA489000_SYS_VOLTAGE_REG_MAX +#define CHARGE_V_MIN RAA489000_SYS_VOLTAGE_REG_MIN +#define CHARGE_V_STEP 64 #endif +#ifdef CONFIG_CHARGER_RAA489000 +#define CHARGE_I_MAX RAA489000_CURRENT_REG_MAX +#else #define CHARGE_I_MAX ISL923X_CURRENT_REG_MAX +#endif /* CONFIG_CHARGER_RAA489000 */ #define CHARGE_I_MIN 4 #define CHARGE_I_OFF 0 #define CHARGE_I_STEP 4 +#ifdef CONFIG_CHARGER_RAA489000 +#define INPUT_I_MAX RAA489000_CURRENT_REG_MAX +#else #define INPUT_I_MAX ISL923X_CURRENT_REG_MAX +#endif /* CONFIG_CHARGER_RAA489000 */ #define INPUT_I_MIN 4 #define INPUT_I_STEP 4 @@ -302,9 +330,9 @@ enum isl9237_fsm_state { /** * Initialize AC & DC prochot threshold * - * @param AC Porchot threshold current in mA: + * @param AC Prochot threshold current in mA: * multiple of 128 up to 6400 mA - * DC Porchot threshold current in mA: + * DC Prochot threshold current in mA: * multiple of 128 up to 12800 mA * Bits below 128mA are truncated (ignored). * @return enum ec_error_list diff --git a/include/config.h b/include/config.h index 550c827df8..1bc0f30006 100644 --- a/include/config.h +++ b/include/config.h @@ -793,6 +793,7 @@ #undef CONFIG_CHARGER_ISL9238 #undef CONFIG_CHARGER_ISL9241 #undef CONFIG_CHARGER_MT6370 +#undef CONFIG_CHARGER_RAA489000 #undef CONFIG_CHARGER_RT9466 #undef CONFIG_CHARGER_RT9467 #undef CONFIG_CHARGER_SY21612 @@ -4781,7 +4782,7 @@ * architecture. */ #if defined(CONFIG_CHARGER_ISL9237) || defined(CONFIG_CHARGER_ISL9238) || \ - defined(CONFIG_CHARGER_ISL9241) + defined(CONFIG_CHARGER_ISL9241) || defined(CONFIG_CHARGER_RAA489000) #define CONFIG_CHARGER_NARROW_VDC #endif -- cgit v1.2.1