From 122fea886b93c12f1c3682c2b801d01cd2bcf0fc Mon Sep 17 00:00:00 2001 From: Aseda Aboagye Date: Fri, 8 May 2020 17:37:28 -0700 Subject: raa489000: Add support for DVC This commit adds support for DVC, Dynamic Voltage Compensation, which is supported by the RAA4890000. In DVC mode, the battery can be charged through an auxiliary RAA489000 operating as a Voltage Regulator. DVC mode is used to autonomously fine tune the charge current without significant involvement from the system. BUG=b:155225932 BRANCH=None TEST=Build and flash waddledoo, verify that battery can be charged from the sub-board. TEST=`make -j buildall` Signed-off-by: Aseda Aboagye Change-Id: Ie6af4fa4abcda2c8695919e30d231d812d7171b5 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2191299 Commit-Queue: Aseda Aboagye Tested-by: Aseda Aboagye Reviewed-by: Diana Z --- driver/charger/isl923x.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ driver/charger/isl923x.h | 18 ++++++++ 2 files changed, 135 insertions(+) (limited to 'driver') diff --git a/driver/charger/isl923x.c b/driver/charger/isl923x.c index bfcfaef590..ae23b03426 100644 --- a/driver/charger/isl923x.c +++ b/driver/charger/isl923x.c @@ -950,6 +950,120 @@ static enum ec_error_list isl923x_get_vbus_voltage(int chgnum, int port, return EC_SUCCESS; } +#ifdef CONFIG_CHARGER_RAA489000 +static enum ec_error_list raa489000_set_vsys_compensation(int chgnum, + struct ocpc_data *o, + int current_ma, + int voltage_mv) +{ + int device_id = 0; + int rv; + int rp1; + int rp2; + int regval; + + /* This should never be called against the primary charger. */ + ASSERT(chgnum != PRIMARY_CHARGER); + + /* Only B0+ silicon supports VSYS compensation. */ + rv = isl923x_device_id(chgnum, &device_id); + if (rv) + return EC_ERROR_UNKNOWN; + + /* + * Note: this makes the assumption that this charger IC is used on the + * primary port as well. + */ + + if (device_id < RAA489000_DEV_ID_B0) + return EC_ERROR_UNIMPLEMENTED; + + /* + * Need to set board resistance values: Rp1 and Rp2. These are expected + * to be fairly constant once we are able to calculate their values. + * + * Rp1 is the total resistance from the right-hand side of the + * auxiliary sense resistor to the actual VSYS node. It should include: + * a. resistance of sub board sense resistor + * b. connector/cable resistance + * c. sub board PCB resistance to the actual VSYS node + * + * Rp2 is the total resistance from the actual VSYS node to the battery. + * It should include: + * a. resistance of primary charger sense resistor (battery side) + * b. Rds(on) of BGATE FET + * c. main board PCB resistance to the battery + * d. battery internal resistance + */ + + /* + * Rp1 is set between 36-156mOhms in 4mOhm increments. This must be + * non-zero in order for compensation to work. The system keeps track + * of combined resistance; we'll assume that Rp2 is what was statically + * defined leaving Rp1 as the difference. If Rp1 is less than 36mOhms, + * then the compensation is disabled. + * + * TODO(b/148980020): When we can calculate Rsys vs Rbatt, update this + * accordingly. + */ + rp1 = o->combined_rsys_rbatt_mo - CONFIG_OCPC_DEF_RBATT_MOHMS; + rp1 = MIN(rp1, RAA489000_RP1_MAX); + rp1 -= RAA489000_RP1_MIN; + if (rp1 < 0) { + if (o->last_vsys == OCPC_UNINIT) + CPRINTS("RAA489000(%d): Disabling DVC (Rp1 < 36mOhms)", + chgnum); + rp1 = 0; + } else { + rp1 /= 4; + rp1++; /* Rp1 min starts at register value 1 */ + } + + /* Rp2 is set between 0-124mOhms in 4mOhm increments. */ + rp2 = CONFIG_OCPC_DEF_RBATT_MOHMS; + rp2 = CLAMP(rp2, RAA489000_RP2_MIN, RAA489000_RP2_MAX); + rp2 /= 4; + + rv |= raw_read16(chgnum, RAA489000_REG_CONTROL10, ®val); + if (!rv) { + /* Set Rp1 and Rp2 */ + regval &= ~RAA489000_C10_RP1_MASK; + regval &= ~RAA489000_C10_RP2_MASK; + regval |= rp2; + regval |= (rp1 << RAA489000_C10_RP1_SHIFT); + + /* Enable DVC mode */ + regval |= RAA489000_C10_ENABLE_DVC_MODE; + + /* Disable charge current loop */ + regval |= RAA489000_C10_DISABLE_DVC_CC_LOOP; + + rv |= raw_write16(chgnum, RAA489000_REG_CONTROL10, regval); + } + + if (rv) { + CPRINTS("%s(%d) Failed to enable DVC!", __func__, chgnum); + return EC_ERROR_UNKNOWN; + } + + /* Lastly, enable DVC fast charge mode for the primary charger IC. */ + rv = raw_read16(PRIMARY_CHARGER, RAA489000_REG_CONTROL10, ®val); + regval |= RAA489000_C10_ENABLE_DVC_CHARGE_MODE; + rv |= raw_write16(PRIMARY_CHARGER, RAA489000_REG_CONTROL10, regval); + if (rv) { + CPRINTS("%s Failed to enable DVC on primary charger!", + __func__); + return EC_ERROR_UNKNOWN; + } + + /* + * We'll need to use the PID loop in order to properly set VSYS such + * such that we get the desired charge current. + */ + return EC_ERROR_UNIMPLEMENTED; +} +#endif /* CONFIG_CHARGER_RAA489000 */ + const struct charger_drv isl923x_drv = { .init = &isl923x_init, .post_init = &isl923x_post_init, @@ -978,4 +1092,7 @@ const struct charger_drv isl923x_drv = { .ramp_is_detected = &isl923x_ramp_is_detected, .ramp_get_current_limit = &isl923x_ramp_get_current_limit, #endif +#ifdef CONFIG_CHARGER_RAA489000 + .set_vsys_compensation = &raa489000_set_vsys_compensation, +#endif }; diff --git a/driver/charger/isl923x.h b/driver/charger/isl923x.h index d581d2560c..d9d11a6e20 100644 --- a/driver/charger/isl923x.h +++ b/driver/charger/isl923x.h @@ -33,6 +33,7 @@ #define ISL923X_REG_MANUFACTURER_ID 0xfe #define ISL923X_REG_DEVICE_ID 0xff #define RAA489000_REG_CONTROL8 0x37 +#define RAA489000_REG_CONTROL10 0x35 /* Sense resistor default values in mOhm */ #define ISL923X_DEFAULT_SENSE_RESISTOR_AC 20 @@ -310,6 +311,23 @@ enum isl9237_fsm_state { #define ISL923X_INFO_DCHOT BIT(11) #define ISL9237_INFO_ACHOT BIT(12) +#define RAA489000_DEV_ID_B0 0x11 + +/* DVC - Dynamic Voltage Compensation */ +#define RAA489000_RP1_MAX 156 +#define RAA489000_RP1_MIN 36 +#define RAA489000_RP2_MAX 124 +#define RAA489000_RP2_MIN 0 + +#define RAA489000_C10_RP2_MASK GENMASK(4, 0) +#define RAA489000_C10_DISABLE_DVC_AUTO_ZERO BIT(5) +#define RAA489000_C10_ENABLE_DVC_TRICKLE_CHARGE BIT(6) +#define RAA489000_C10_DISABLE_DVC_CC_LOOP BIT(8) +#define RAA489000_C10_ENABLE_DVC_CHARGE_MODE BIT(9) +#define RAA489000_C10_RP1_MASK GENMASK(14, 10) +#define RAA489000_C10_RP1_SHIFT 10 +#define RAA489000_C10_ENABLE_DVC_MODE BIT(15) + #if defined(CONFIG_CHARGER_ISL9237) #define CHARGER_NAME "isl9237" #define CHARGE_V_MAX ISL9237_SYS_VOLTAGE_REG_MAX -- cgit v1.2.1