summaryrefslogtreecommitdiff
path: root/driver/charger/isl9241.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/charger/isl9241.c')
-rw-r--r--driver/charger/isl9241.c347
1 files changed, 237 insertions, 110 deletions
diff --git a/driver/charger/isl9241.c b/driver/charger/isl9241.c
index bd84d30755..9ca2e9f3e0 100644
--- a/driver/charger/isl9241.c
+++ b/driver/charger/isl9241.c
@@ -1,4 +1,4 @@
-/* Copyright 2019 The Chromium OS Authors. All rights reserved.
+/* Copyright 2019 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
@@ -29,20 +29,20 @@
#endif
/* Sense resistor default values in milli Ohm */
-#define ISL9241_DEFAULT_RS1 20 /* Input current sense resistor */
-#define ISL9241_DEFAULT_RS2 10 /* Battery charge current sense resistor */
+#define ISL9241_DEFAULT_RS1 20 /* Input current sense resistor */
+#define ISL9241_DEFAULT_RS2 10 /* Battery charge current sense resistor */
#define BOARD_RS1 CONFIG_CHARGER_SENSE_RESISTOR_AC
#define BOARD_RS2 CONFIG_CHARGER_SENSE_RESISTOR
-#define BC_REG_TO_CURRENT(REG) (((REG) * ISL9241_DEFAULT_RS2) / BOARD_RS2)
-#define BC_CURRENT_TO_REG(CUR) (((CUR) * BOARD_RS2) / ISL9241_DEFAULT_RS2)
+#define BC_REG_TO_CURRENT(REG) (((REG)*ISL9241_DEFAULT_RS2) / BOARD_RS2)
+#define BC_CURRENT_TO_REG(CUR) (((CUR)*BOARD_RS2) / ISL9241_DEFAULT_RS2)
-#define AC_REG_TO_CURRENT(REG) (((REG) * ISL9241_DEFAULT_RS1) / BOARD_RS1)
-#define AC_CURRENT_TO_REG(CUR) (((CUR) * BOARD_RS1) / ISL9241_DEFAULT_RS1)
+#define AC_REG_TO_CURRENT(REG) (((REG)*ISL9241_DEFAULT_RS1) / BOARD_RS1)
+#define AC_CURRENT_TO_REG(CUR) (((CUR)*BOARD_RS1) / ISL9241_DEFAULT_RS1)
/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_CHARGER, "ISL9241 " format, ##args)
static int learn_mode;
@@ -51,29 +51,28 @@ K_MUTEX_DEFINE(control1_mutex_isl9241);
/* Charger parameters */
static const struct charger_info isl9241_charger_info = {
- .name = CHARGER_NAME,
- .voltage_max = CHARGE_V_MAX,
- .voltage_min = CHARGE_V_MIN,
+ .name = CHARGER_NAME,
+ .voltage_max = CHARGE_V_MAX,
+ .voltage_min = CHARGE_V_MIN,
.voltage_step = CHARGE_V_STEP,
- .current_max = BC_REG_TO_CURRENT(CHARGE_I_MAX),
- .current_min = BC_REG_TO_CURRENT(CHARGE_I_MIN),
+ .current_max = BC_REG_TO_CURRENT(CHARGE_I_MAX),
+ .current_min = BC_REG_TO_CURRENT(CHARGE_I_MIN),
.current_step = BC_REG_TO_CURRENT(CHARGE_I_STEP),
- .input_current_max = AC_REG_TO_CURRENT(INPUT_I_MAX),
- .input_current_min = AC_REG_TO_CURRENT(INPUT_I_MIN),
+ .input_current_max = AC_REG_TO_CURRENT(INPUT_I_MAX),
+ .input_current_min = AC_REG_TO_CURRENT(INPUT_I_MIN),
.input_current_step = AC_REG_TO_CURRENT(INPUT_I_STEP),
};
static enum ec_error_list isl9241_discharge_on_ac(int chgnum, int enable);
static enum ec_error_list isl9241_discharge_on_ac_unsafe(int chgnum,
- int enable);
+ int enable);
static enum ec_error_list isl9241_discharge_on_ac_weak_disable(int chgnum);
static inline enum ec_error_list isl9241_read(int chgnum, int offset,
int *value)
{
int rv = i2c_read16(chg_chips[chgnum].i2c_port,
- chg_chips[chgnum].i2c_addr_flags,
- offset, value);
+ chg_chips[chgnum].i2c_addr_flags, offset, value);
if (rv)
CPRINTS("%s failed (%d)", __func__, rv);
@@ -84,8 +83,7 @@ static inline enum ec_error_list isl9241_write(int chgnum, int offset,
int value)
{
int rv = i2c_write16(chg_chips[chgnum].i2c_port,
- chg_chips[chgnum].i2c_addr_flags,
- offset, value);
+ chg_chips[chgnum].i2c_addr_flags, offset, value);
if (rv)
CPRINTS("%s failed (%d)", __func__, rv);
@@ -97,8 +95,8 @@ static inline enum ec_error_list isl9241_update(int chgnum, int offset,
enum mask_update_action action)
{
int rv = i2c_update16(chg_chips[chgnum].i2c_port,
- chg_chips[chgnum].i2c_addr_flags,
- offset, mask, action);
+ chg_chips[chgnum].i2c_addr_flags, offset, mask,
+ action);
if (rv)
CPRINTS("%s failed (%d)", __func__, rv);
@@ -183,6 +181,19 @@ static const struct charger_info *isl9241_get_info(int chgnum)
return &isl9241_charger_info;
}
+static enum ec_error_list isl9241_bypass_mode_enabled(int chgnum, int *enabled)
+{
+ int reg, rv;
+
+ rv = isl9241_read(chgnum, ISL9241_REG_CONTROL0, &reg);
+ if (rv)
+ return rv;
+
+ *enabled = !!(reg & ISL9241_CONTROL0_EN_BYPASS_GATE);
+
+ return EC_SUCCESS;
+}
+
static enum ec_error_list isl9241_get_status(int chgnum, int *status)
{
int rv;
@@ -207,6 +218,13 @@ static enum ec_error_list isl9241_get_status(int chgnum, int *status)
if (reg & ISL9241_INFORMATION2_ACOK_PIN)
*status |= CHARGER_AC_PRESENT;
+ /* Bypass mode status */
+ rv = isl9241_bypass_mode_enabled(chgnum, &reg);
+ if (rv)
+ return rv;
+ if (reg)
+ *status |= CHARGER_BYPASS_MODE;
+
return EC_SUCCESS;
}
@@ -227,15 +245,16 @@ static enum ec_error_list isl9241_set_mode(int chgnum, int mode)
* MinSystemVoltage 0x00h = disables all battery charging
*/
rv = isl9241_write(chgnum, ISL9241_REG_MIN_SYSTEM_VOLTAGE,
- mode & CHARGE_FLAG_INHIBIT_CHARGE ?
- 0 : battery_get_info()->voltage_min);
+ mode & CHARGE_FLAG_INHIBIT_CHARGE ?
+ 0 :
+ battery_get_info()->voltage_min);
if (rv)
return rv;
/* POR reset */
if (mode & CHARGE_FLAG_POR_RESET) {
rv = isl9241_write(chgnum, ISL9241_REG_CONTROL3,
- ISL9241_CONTROL3_DIGITAL_RESET);
+ ISL9241_CONTROL3_DIGITAL_RESET);
}
return rv;
@@ -256,7 +275,7 @@ static enum ec_error_list isl9241_get_current(int chgnum, int *current)
static enum ec_error_list isl9241_set_current(int chgnum, int current)
{
return isl9241_write(chgnum, ISL9241_REG_CHG_CURRENT_LIMIT,
- BC_CURRENT_TO_REG(current));
+ BC_CURRENT_TO_REG(current));
}
static enum ec_error_list isl9241_get_voltage(int chgnum, int *voltage)
@@ -317,6 +336,38 @@ error:
return rv;
}
+static enum ec_error_list isl9241_get_vsys_voltage(int chgnum, int port,
+ int *voltage)
+{
+ int val = 0;
+ int rv;
+
+ rv = isl9241_update(chgnum, ISL9241_REG_CONTROL3,
+ ISL9241_CONTROL3_ENABLE_ADC, MASK_SET);
+ if (rv) {
+ CPRINTS("Could not enable ADC for Vsys. (rv=%d)", rv);
+ return rv;
+ }
+
+ usleep(ISL9241_ADC_POLLING_TIME_US);
+
+ /* Read voltage ADC value */
+ rv = isl9241_read(chgnum, ISL9241_REG_VSYS_ADC_RESULTS, &val);
+ if (rv) {
+ CPRINTS("Could not read Vsys. (rv=%d)", rv);
+ isl9241_update(chgnum, ISL9241_REG_CONTROL3,
+ ISL9241_CONTROL3_ENABLE_ADC, MASK_CLR);
+ return rv;
+ }
+
+ /* Adjust adc_val. Same as Vin. */
+ val >>= ISL9241_VIN_ADC_BIT_OFFSET;
+ val *= ISL9241_VIN_ADC_STEP_MV;
+ *voltage = val;
+
+ return EC_SUCCESS;
+}
+
static enum ec_error_list isl9241_post_init(int chgnum)
{
return EC_SUCCESS;
@@ -326,12 +377,11 @@ static enum ec_error_list isl9241_post_init(int chgnum)
* Writes to ISL9241_REG_CONTROL1, unsafe as it does not lock
* control1_mutex_isl9241.
*/
-static enum ec_error_list isl9241_discharge_on_ac_unsafe(int chgnum,
- int enable)
+static enum ec_error_list isl9241_discharge_on_ac_unsafe(int chgnum, int enable)
{
int rv = isl9241_update(chgnum, ISL9241_REG_CONTROL1,
- ISL9241_CONTROL1_LEARN_MODE,
- (enable) ? MASK_SET : MASK_CLR);
+ ISL9241_CONTROL1_LEARN_MODE,
+ (enable) ? MASK_SET : MASK_CLR);
if (!rv)
learn_mode = enable;
@@ -417,7 +467,7 @@ static bool isl9241_is_ac_present(int chgnum)
if (rv == EC_SUCCESS)
ac_is_present = !!(reg & ISL9241_INFORMATION2_ACOK_PIN);
- return ac_is_present;
+ return ac_is_present;
}
/*
@@ -448,26 +498,33 @@ static enum ec_error_list isl9241_bypass_to_bat(int chgnum)
{
const struct battery_info *bi = battery_get_info();
+ CPRINTS("bypass -> bat");
+
/* 1: Disable force forward buck/reverse boost. */
isl9241_update(chgnum, ISL9241_REG_CONTROL4,
ISL9241_CONTROL4_FORCE_BUCK_MODE, MASK_CLR);
+
/*
* 2: Turn off BYPSG, turn on NGATE, disable charge pump 100%, disable
* Vin<Vout comparator.
*/
isl9241_write(chgnum, ISL9241_REG_CONTROL0, 0);
+
/* 3: Set MaxSysVoltage to full charge. */
isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, bi->voltage_max);
+
/* 4: Disable ADC. */
isl9241_update(chgnum, ISL9241_REG_CONTROL3,
ISL9241_CONTROL3_ENABLE_ADC, MASK_CLR);
+
/* 5: Set BGATE to normal operation. */
- isl9241_update(chgnum, ISL9241_REG_CONTROL1,
- ISL9241_CONTROL1_BGATE_OFF, MASK_CLR);
+ isl9241_update(chgnum, ISL9241_REG_CONTROL1, ISL9241_CONTROL1_BGATE_OFF,
+ MASK_CLR);
+
/* 6: Set ACOK reference to normal value. TODO: Revisit. */
isl9241_write(chgnum, ISL9241_REG_ACOK_REFERENCE,
ISL9241_MV_TO_ACOK_REFERENCE(
- ISL9241_ACOK_REF_LOW_VOLTAGE_ADAPTER_MV));
+ ISL9241_ACOK_REF_LOW_VOLTAGE_ADAPTER_MV));
return EC_SUCCESS;
}
@@ -477,6 +534,8 @@ static enum ec_error_list isl9241_bypass_to_bat(int chgnum)
*/
static enum ec_error_list isl9241_bypass_chrg_to_bat(int chgnum)
{
+ CPRINTS("bypass_chrg -> bat");
+
/* 1: Disable force forward buck/reverse boost. */
isl9241_update(chgnum, ISL9241_REG_CONTROL4,
ISL9241_CONTROL4_FORCE_BUCK_MODE, MASK_CLR);
@@ -493,8 +552,8 @@ static enum ec_error_list isl9241_bypass_chrg_to_bat(int chgnum)
isl9241_update(chgnum, ISL9241_REG_CONTROL3,
ISL9241_CONTROL3_ENABLE_ADC, MASK_CLR);
/* 6: Set BGATE to normal operation. */
- isl9241_update(chgnum, ISL9241_REG_CONTROL1,
- ISL9241_CONTROL1_BGATE_OFF, MASK_CLR);
+ isl9241_update(chgnum, ISL9241_REG_CONTROL1, ISL9241_CONTROL1_BGATE_OFF,
+ MASK_CLR);
/* 7: Set ACOK reference to normal value. TODO: Revisit. */
isl9241_write(chgnum, ISL9241_REG_ACOK_REFERENCE,
ISL9241_MV_TO_ACOK_REFERENCE(3600));
@@ -509,6 +568,8 @@ static enum ec_error_list isl9241_nvdc_chrg_to_nvdc(int chgnum)
{
enum ec_error_list rv;
+ CPRINTS("nvdc_chrg -> nvdc");
+
/* L: If we're in NVDC+Chg, first transition to NVDC. */
/* 1: Disable fast charge. */
rv = isl9241_set_current(chgnum, 0);
@@ -530,52 +591,82 @@ static enum ec_error_list isl9241_enable_bypass_mode(int chgnum, bool enable);
*/
static enum ec_error_list isl9241_nvdc_to_bypass(int chgnum)
{
- int voltage;
+ const struct battery_info *bi = battery_get_info();
+ const int charge_current = charge_manager_get_charger_current();
+ const int charge_voltage = charge_manager_get_charger_voltage();
+ int vsys, vsys_target;
+ timestamp_t deadline;
+
+ CPRINTS("nvdc -> bypass");
/* 1: Set adapter current limit. */
- isl9241_set_input_current_limit(
- chgnum, charge_manager_get_charger_current());
+ isl9241_set_input_current_limit(chgnum, charge_current);
+
/* 2: Set charge pumps to 100%. */
isl9241_update(chgnum, ISL9241_REG_CONTROL0,
ISL9241_CONTROL0_EN_CHARGE_PUMPS, MASK_SET);
+
/* 3: Enable ADC. */
isl9241_update(chgnum, ISL9241_REG_CONTROL3,
ISL9241_CONTROL3_ENABLE_ADC, MASK_SET);
+
/* 4: Turn on Vin/Vout comparator. */
isl9241_update(chgnum, ISL9241_REG_CONTROL0,
ISL9241_CONTROL0_EN_VIN_VOUT_COMP, MASK_SET);
- /* 5: Set ACOK reference higher than battery full voltage.
+
+ /* 5: Set ACOK reference higher than battery full voltage. */
isl9241_write(chgnum, ISL9241_REG_ACOK_REFERENCE,
- ISL9241_MV_TO_ACOK_REFERENCE(
- battery_full_voltage_mv + 800));
- */
+ ISL9241_MV_TO_ACOK_REFERENCE(bi->voltage_max + 800));
+
/* 6*: Reduce system load below ACLIM. */
/* 7: Turn off BGATE */
- isl9241_update(chgnum, ISL9241_REG_CONTROL1,
- ISL9241_CONTROL1_BGATE_OFF, MASK_SET);
+ isl9241_update(chgnum, ISL9241_REG_CONTROL1, ISL9241_CONTROL1_BGATE_OFF,
+ MASK_SET);
+
/* 8*: Set MaxSysVoltage to VADP. */
- isl9241_get_vbus_voltage(chgnum, 0, &voltage);
- isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, voltage - 256);
+ vsys_target = MIN(charge_voltage - 256, CHARGE_V_MAX);
+ isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, vsys_target);
+
/* 9*: Wait until VSYS == MaxSysVoltage. */
+ deadline.val = get_time().val + ISL9241_BYPASS_VSYS_TIMEOUT_MS * MSEC;
+ do {
+ msleep(ISL9241_BYPASS_VSYS_TIMEOUT_MS / 10);
+ if (isl9241_get_vsys_voltage(chgnum, 0, &vsys)) {
+ CPRINTS("Aborting bypass mode. Vsys is unknown.");
+ return EC_ERROR_UNKNOWN;
+ }
+ if (timestamp_expired(deadline, NULL)) {
+ CPRINTS("Aborting bypass mode. Vsys too low (%d < %d)",
+ vsys, vsys_target);
+ return EC_ERROR_TIMEOUT;
+ }
+ } while (vsys < vsys_target - 256);
+
/* 10*: Turn on Bypass gate */
isl9241_update(chgnum, ISL9241_REG_CONTROL0,
ISL9241_CONTROL0_EN_BYPASS_GATE, MASK_SET);
+
/* 11: Wait 1 ms. */
msleep(1);
+
/* 12*: Turn off NGATE. */
- isl9241_update(chgnum, ISL9241_REG_CONTROL0,
- ISL9241_CONTROL0_NGATE_OFF, MASK_SET);
+ isl9241_update(chgnum, ISL9241_REG_CONTROL0, ISL9241_CONTROL0_NGATE_OFF,
+ MASK_SET);
+
/* 14*: Stop switching. */
isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, 0);
+
/* 15: Set BGATE to normal operation. */
- isl9241_update(chgnum, ISL9241_REG_CONTROL1,
- ISL9241_CONTROL1_BGATE_OFF, MASK_CLR);
- /*
- * Suggestion-1: If ACOK goes low before step A16, stop here
- * then execute the steps for Bypass to BAT to abort.
- */
+ isl9241_update(chgnum, ISL9241_REG_CONTROL1, ISL9241_CONTROL1_BGATE_OFF,
+ MASK_CLR);
+
if (!isl9241_is_ac_present(chgnum))
- return isl9241_enable_bypass_mode(chgnum, false);
+ /*
+ * Suggestion: If ACOK goes low before step A16, stop
+ * executing commands and complete steps for Bypass to BAT.
+ */
+ return EC_ERROR_PARAM1;
+
/* 16: Enable 10 mA discharge on CSOP. */
/* 17: Read diode emulation active bit. */
/* 18: Disable 10mA discharge on CSOP. */
@@ -583,12 +674,12 @@ static enum ec_error_list isl9241_nvdc_to_bypass(int chgnum)
isl9241_update(chgnum, ISL9241_REG_CONTROL4,
ISL9241_CONTROL4_FORCE_BUCK_MODE, MASK_SET);
- /*
- * Suggestion-2 and 3: If AC is removed on or after A16,
- * complete all steps then execute Bypass to BAT to revert.
- */
if (!isl9241_is_ac_present(chgnum))
- return isl9241_enable_bypass_mode(chgnum, false);
+ /*
+ * Suggestion: If AC is removed on or after A16, complete all
+ * 19 steps then execute Bypass to BAT.
+ */
+ return EC_ERROR_PARAM2;
return EC_SUCCESS;
}
@@ -598,12 +689,24 @@ static enum ec_error_list isl9241_nvdc_to_bypass(int chgnum)
*/
static enum ec_error_list isl9241_bypass_chrg_to_bypass(int chgnum)
{
+ int rv;
+
+ CPRINTS("bypass_chrg -> bypass");
+
/* 1: Stop switching. */
- isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, 0);
+ rv = isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, 0);
+ if (rv)
+ return rv;
+
/* 2: Disable fast charge. */
- isl9241_write(chgnum, ISL9241_REG_CHG_CURRENT_LIMIT, 0);
+ rv = isl9241_write(chgnum, ISL9241_REG_CHG_CURRENT_LIMIT, 0);
+ if (rv)
+ return rv;
+
/* 3: Disable trickle charge. */
- isl9241_write(chgnum, ISL9241_REG_MIN_SYSTEM_VOLTAGE, 0);
+ rv = isl9241_write(chgnum, ISL9241_REG_MIN_SYSTEM_VOLTAGE, 0);
+ if (rv)
+ return rv;
return EC_SUCCESS;
}
@@ -615,26 +718,44 @@ static enum ec_error_list isl9241_bypass_to_nvdc(int chgnum)
{
const struct battery_info *bi = battery_get_info();
int voltage;
+ int rv;
+
+ CPRINTS("bypass -> nvdc");
/* 1*: Reduce system load below ACLIM. */
/* 3*: Disable force forward buck/reverse boost. */
- isl9241_update(chgnum, ISL9241_REG_CONTROL4,
- ISL9241_CONTROL4_FORCE_BUCK_MODE, MASK_CLR);
+ rv = isl9241_update(chgnum, ISL9241_REG_CONTROL4,
+ ISL9241_CONTROL4_FORCE_BUCK_MODE, MASK_CLR);
+ if (rv)
+ return rv;
+
/* 6*: Set MaxSysVoltage to VADP. */
- isl9241_get_vbus_voltage(chgnum, 0, &voltage);
- isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, voltage - 256);
+ rv = isl9241_get_vbus_voltage(chgnum, 0, &voltage);
+ if (rv)
+ return rv;
+ rv = isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE,
+ voltage - 256);
+ if (rv)
+ return rv;
+
/* 7*: Wait until VSYS == MaxSysVoltage. */
msleep(1);
+
/* 8*: Turn on NGATE. */
- isl9241_update(chgnum, ISL9241_REG_CONTROL0,
- ISL9241_CONTROL0_NGATE_OFF, MASK_CLR);
+ rv = isl9241_update(chgnum, ISL9241_REG_CONTROL0,
+ ISL9241_CONTROL0_NGATE_OFF, MASK_CLR);
+ if (rv)
+ return rv;
+
/* 10*: Turn off Bypass gate */
- isl9241_update(chgnum, ISL9241_REG_CONTROL0,
- ISL9241_CONTROL0_EN_BYPASS_GATE, MASK_CLR);
- /* 12*: Set MaxSysVoltage to full charge. */
- isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE, bi->voltage_max);
+ rv = isl9241_update(chgnum, ISL9241_REG_CONTROL0,
+ ISL9241_CONTROL0_EN_BYPASS_GATE, MASK_CLR);
+ if (rv)
+ return rv;
- return EC_SUCCESS;
+ /* 12*: Set MaxSysVoltage to full charge. */
+ return isl9241_write(chgnum, ISL9241_REG_MAX_SYSTEM_VOLTAGE,
+ bi->voltage_max);
}
static enum ec_error_list isl9241_enable_bypass_mode(int chgnum, bool enable)
@@ -646,37 +767,48 @@ static enum ec_error_list isl9241_enable_bypass_mode(int chgnum, bool enable)
if (isl9241_is_in_chrg(chgnum)) {
/* (Optional) L (then A) */
rv = isl9241_nvdc_chrg_to_nvdc(chgnum);
- CPRINTS("%s nvdc_chrg -> nvdc",
- rv ? "Failed" : "Succeeded");
+ if (rv)
+ CPRINTS("nvdc_chrg -> nvdc failed(%d)", rv);
}
/* A */
rv = isl9241_nvdc_to_bypass(chgnum);
- CPRINTS("%s nvdc -> bypass", rv ? "Failed" : "Succeeded");
+ if (rv == EC_ERROR_PARAM1 || rv == EC_ERROR_PARAM2) {
+ CPRINTS("AC removed (%d) in nvdc -> bypass mode", rv);
+ return isl9241_bypass_to_bat(chgnum);
+ } else if (rv) {
+ CPRINTS("Failed to enable bypass mode(%d)", rv);
+ return isl9241_bypass_to_nvdc(chgnum);
+ }
return rv;
- } else if (isl9241_is_ac_present(chgnum)) {
- /* Switch to NVDC (e.g. BJ -> Type-C) */
+ }
+
+ /* Disable */
+ if (isl9241_is_ac_present(chgnum)) {
+ /* Switch to another AC (e.g. BJ -> Type-C) */
if (isl9241_is_in_chrg(chgnum)) {
/* J (then B) */
rv = isl9241_bypass_chrg_to_bypass(chgnum);
- CPRINTS("%s bypass_chrg -> bypass",
- rv ? "Failed" : "Succeeded");
+ if (rv)
+ CPRINTS("bypass_chrg -> bypass failed(%d)", rv);
}
/* B */
rv = isl9241_bypass_to_nvdc(chgnum);
- CPRINTS("%s bypass -> nvdc", rv ? "Failed" : "Succeeded");
+ if (rv)
+ CPRINTS("bypass -> nvdc failed(%d)", rv);
return rv;
} else {
/* AC removal */
if (isl9241_is_in_chrg(chgnum)) {
/* M */
rv = isl9241_bypass_chrg_to_bat(chgnum);
- CPRINTS("%s bypass_chrg -> bat",
- rv ? "Failed" : "Succeeded");
- return rv;
+ if (rv)
+ CPRINTS("bypass_chrg -> bat failed(%d)", rv);
+ } else {
+ /* M' */
+ rv = isl9241_bypass_to_bat(chgnum);
+ if (rv)
+ CPRINTS("bypass -> bat failed(%d)", rv);
}
- /* M */
- rv = isl9241_bypass_to_bat(chgnum);
- CPRINTS("%s bypass -> bat", rv ? "Failed" : "Succeeded");
return rv;
}
@@ -714,11 +846,11 @@ static void isl9241_init(int chgnum)
* [15:13]: Trickle Charging Current (battery pre-charge current)
* [10:9] : Prochot# Debounce time (1000us)
*/
- if (isl9241_update(chgnum, ISL9241_REG_CONTROL2,
- (ISL9241_CONTROL2_TRICKLE_CHG_CURR(
- bi->precharge_current) |
- ISL9241_CONTROL2_PROCHOT_DEBOUNCE_1000),
- MASK_SET))
+ if (isl9241_update(
+ chgnum, ISL9241_REG_CONTROL2,
+ (ISL9241_CONTROL2_TRICKLE_CHG_CURR(bi->precharge_current) |
+ ISL9241_CONTROL2_PROCHOT_DEBOUNCE_1000),
+ MASK_SET))
goto init_fail;
/*
@@ -726,8 +858,7 @@ static void isl9241_init(int chgnum)
* [14]: ACLIM Reload (Do not reload)
*/
if (isl9241_update(chgnum, ISL9241_REG_CONTROL3,
- ISL9241_CONTROL3_ACLIM_RELOAD,
- MASK_SET))
+ ISL9241_CONTROL3_ACLIM_RELOAD, MASK_SET))
goto init_fail;
/*
@@ -735,14 +866,12 @@ static void isl9241_init(int chgnum)
* [13]: Slew rate control enable (sets VSYS ramp to 8mV/us)
*/
if (isl9241_update(chgnum, ISL9241_REG_CONTROL4,
- ISL9241_CONTROL4_SLEW_RATE_CTRL,
- MASK_SET))
+ ISL9241_CONTROL4_SLEW_RATE_CTRL, MASK_SET))
goto init_fail;
#ifndef CONFIG_CHARGE_RAMP_HW
if (isl9241_update(chgnum, ISL9241_REG_CONTROL0,
- ISL9241_CONTROL0_INPUT_VTG_REGULATION,
- MASK_SET))
+ ISL9241_CONTROL0_INPUT_VTG_REGULATION, MASK_SET))
goto init_fail;
#endif
@@ -751,7 +880,7 @@ static void isl9241_init(int chgnum)
goto init_fail;
ctl_val &= ~ISL9241_CONTROL1_SWITCHING_FREQ_MASK;
ctl_val |= ((CONFIG_ISL9241_SWITCHING_FREQ << 7) &
- ISL9241_CONTROL1_SWITCHING_FREQ_MASK);
+ ISL9241_CONTROL1_SWITCHING_FREQ_MASK);
if (isl9241_write(chgnum, ISL9241_REG_CONTROL1, ctl_val))
goto init_fail;
#endif
@@ -823,22 +952,19 @@ static int isl9241_ramp_get_current_limit(int chgnum)
*/
static void isl9241_restart_charge_voltage_when_full(void)
{
- if (!chipset_in_or_transitioning_to_state(CHIPSET_STATE_ON)
- && charge_get_state() == PWR_STATE_CHARGE_NEAR_FULL
- && battery_get_disconnect_state() == BATTERY_NOT_DISCONNECTED) {
+ if (!chipset_in_or_transitioning_to_state(CHIPSET_STATE_ON) &&
+ charge_get_state() == PWR_STATE_CHARGE_NEAR_FULL &&
+ battery_get_disconnect_state() == BATTERY_NOT_DISCONNECTED) {
charger_discharge_on_ac(1);
msleep(50);
charger_discharge_on_ac(0);
}
}
-DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE,
- isl9241_restart_charge_voltage_when_full,
+DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, isl9241_restart_charge_voltage_when_full,
HOOK_PRIO_DEFAULT);
-DECLARE_HOOK(HOOK_CHIPSET_SUSPEND,
- isl9241_restart_charge_voltage_when_full,
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, isl9241_restart_charge_voltage_when_full,
HOOK_PRIO_DEFAULT);
-DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN,
- isl9241_restart_charge_voltage_when_full,
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, isl9241_restart_charge_voltage_when_full,
HOOK_PRIO_DEFAULT);
/*****************************************************************************/
@@ -884,6 +1010,7 @@ const struct charger_drv isl9241_drv = {
.set_voltage = &isl9241_set_voltage,
.discharge_on_ac = &isl9241_discharge_on_ac,
.get_vbus_voltage = &isl9241_get_vbus_voltage,
+ .get_vsys_voltage = &isl9241_get_vsys_voltage,
.set_input_current_limit = &isl9241_set_input_current_limit,
.get_input_current_limit = &isl9241_get_input_current_limit,
.manufacturer_id = &isl9241_manufacturer_id,