charger: bq25703: Exit low power mode prior to reading ADC

An ADC conversion requires ~10 msec. However, if the bq25703 is in low
power mode, then this conversion time jumps to ~55 msec. This CL adds
a method to exit/enter low power mode and adds a call to exit low
power mode prior to starting the ADC conversion. Following the
conversion, low power mode is entered again.

BRANCH=none
BUG=b:79771760
TEST=Connected AC power and verified that EC console error message
'Could not read input current limit ADC' is no longer shown. In
addition, had instrumented this the ADC conversion with GPIO signals
and verified the conversion times before/after exiting low power mode.

Change-Id: I13f36e6261e219adbc8624f71bf7916bbc631b10
Signed-off-by: Scott Collyer <scollyer@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1069768
Commit-Ready: Scott Collyer <scollyer@chromium.org>
Tested-by: Scott Collyer <scollyer@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
This commit is contained in:
Scott Collyer
2018-05-22 16:24:28 -07:00
committed by chrome-bot
parent b14614b60c
commit bbc34f225e
2 changed files with 54 additions and 2 deletions

View File

@@ -64,6 +64,40 @@ static inline int raw_write16(int offset, int value)
return i2c_write16(I2C_PORT_CHARGER, BQ25703_I2C_ADDR1, offset, value);
}
static int bq25703_get_low_power_mode(int *mode)
{
int rv;
int reg;
rv = raw_read16(BQ25703_REG_CHARGE_OPTION_0, &reg);
if (rv)
return rv;
*mode = !!(reg & BQ25703_CHARGE_OPTION_0_LOW_POWER_MODE);
return EC_SUCCESS;
}
static int bq25703_set_low_power_mode(int enable)
{
int rv;
int reg;
rv = raw_read16(BQ25703_REG_CHARGE_OPTION_0, &reg);
if (rv)
return rv;
if (enable)
reg |= BQ25703_CHARGE_OPTION_0_LOW_POWER_MODE;
else
reg &= ~BQ25703_CHARGE_OPTION_0_LOW_POWER_MODE;
rv = raw_write16(BQ25703_REG_CHARGE_OPTION_0, reg);
if (rv)
return rv;
return EC_SUCCESS;
}
/* Charger interfaces */
@@ -257,19 +291,36 @@ int chg_ramp_is_detected(void)
int chg_ramp_get_current_limit(void)
{
int reg;
int mode;
int tries_left = 8;
/* Save current mode to restore same state after ADC read */
if (bq25703_get_low_power_mode(&mode))
goto error;
/* Exit low power mode so ADC conversion takes typical time */
if (bq25703_set_low_power_mode(0))
goto error;
/* Turn on the ADC for one reading */
reg = BQ25703_ADC_OPTION_ADC_START | BQ25703_ADC_OPTION_EN_ADC_IIN;
if (raw_write16(BQ25703_REG_ADC_OPTION, reg))
goto error;
/* Wait until the ADC operation completes. Typically 10ms */
/*
* Wait until the ADC operation completes. The spec says typical
* conversion time is 10 msec. If low power mode isn't exited first,
* then the conversion time jumps to ~60 msec.
*/
do {
msleep(2);
raw_read16(BQ25703_REG_ADC_OPTION, &reg);
} while (--tries_left && (reg & BQ25703_ADC_OPTION_ADC_START));
/* ADC reading attempt complete, go back to low power mode */
if (bq25703_set_low_power_mode(mode))
goto error;
/* Could not complete read */
if (reg & BQ25703_ADC_OPTION_ADC_START)
goto error;
@@ -282,7 +333,7 @@ int chg_ramp_get_current_limit(void)
return reg * BQ25703_ADC_IIN_STEP_MA;
error:
CPRINTF("Could not read input current limit ADC!");
CPRINTF("Could not read input current limit ADC!\n");
return 0;
}
#endif /* CONFIG_CHARGE_RAMP_HW */

View File

@@ -39,6 +39,7 @@
#define BQ25703_REG_DEVICE_ADDRESS 0x2F
/* ChargeOption0 Register */
#define BQ25703_CHARGE_OPTION_0_LOW_POWER_MODE (1 << 15)
#define BQ25703_CHARGE_OPTION_0_EN_LEARN (1 << 5)
#define BQ25703_CHARGE_OPTION_0_CHRG_INHIBIT (1 << 0)