qpnp-fg-gen3: support configuring ESR FCC based on charging status
Currently, fuel gauge assumes that the battery charging current is provided only by the main charger. When ESR pulse is needed, it notifies only the main charger to lower its FCC. However, with parallel charger also supplying the FCC to the battery, the main charger can end up increasing its FCC instead of lowering it. This is because of the fact that FCC of main charger is lower than the total battery charging current because of the current distribution to the parallel charger and the code sent by FG allows it to increase its FCC. Fix this by controlling ESR FCC current code to 300mA in software when the device is charging and the parallel charger is enabled. Switch back to hardware control when the device is not charging or parallel charger is disabled. Change-Id: I0e6e600f72f9ef8864f9b775df88f674de9cb52c Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
This commit is contained in:
parent
416ddbdbf3
commit
e0520b6c77
2 changed files with 83 additions and 0 deletions
|
@ -259,6 +259,7 @@ struct fg_chip {
|
|||
struct power_supply *batt_psy;
|
||||
struct power_supply *usb_psy;
|
||||
struct power_supply *dc_psy;
|
||||
struct power_supply *parallel_psy;
|
||||
struct iio_channel *batt_id_chan;
|
||||
struct fg_memif *sram;
|
||||
struct fg_irq_info *irqs;
|
||||
|
@ -291,6 +292,7 @@ struct fg_chip {
|
|||
bool charge_empty;
|
||||
bool recharge_soc_adjusted;
|
||||
bool ki_coeff_dischg_en;
|
||||
bool esr_fcc_ctrl_en;
|
||||
struct completion soc_update;
|
||||
struct completion soc_ready;
|
||||
struct delayed_work profile_load_work;
|
||||
|
|
|
@ -909,6 +909,17 @@ static bool is_charger_available(struct fg_chip *chip)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool is_parallel_charger_available(struct fg_chip *chip)
|
||||
{
|
||||
if (!chip->parallel_psy)
|
||||
chip->parallel_psy = power_supply_get_by_name("parallel");
|
||||
|
||||
if (!chip->parallel_psy)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int fg_save_learned_cap_to_sram(struct fg_chip *chip)
|
||||
{
|
||||
int16_t cc_mah;
|
||||
|
@ -1381,6 +1392,72 @@ static int fg_adjust_recharge_soc(struct fg_chip *chip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fg_esr_fcc_config(struct fg_chip *chip)
|
||||
{
|
||||
union power_supply_propval prop = {0, };
|
||||
int rc;
|
||||
bool parallel_en = false;
|
||||
|
||||
if (is_parallel_charger_available(chip)) {
|
||||
rc = power_supply_get_property(chip->parallel_psy,
|
||||
POWER_SUPPLY_PROP_CHARGING_ENABLED, &prop);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in reading charging_enabled from parallel_psy, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
parallel_en = prop.intval;
|
||||
}
|
||||
|
||||
fg_dbg(chip, FG_POWER_SUPPLY, "status: %d parallel_en: %d esr_fcc_ctrl_en: %d\n",
|
||||
chip->status, parallel_en, chip->esr_fcc_ctrl_en);
|
||||
|
||||
if (chip->status == POWER_SUPPLY_STATUS_CHARGING && parallel_en) {
|
||||
if (chip->esr_fcc_ctrl_en)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* When parallel charging is enabled, configure ESR FCC to
|
||||
* 300mA to trigger an ESR pulse. Without this, FG can ask
|
||||
* the main charger to increase FCC when it is supposed to
|
||||
* decrease it.
|
||||
*/
|
||||
rc = fg_masked_write(chip, BATT_INFO_ESR_FAST_CRG_CFG(chip),
|
||||
ESR_FAST_CRG_IVAL_MASK |
|
||||
ESR_FAST_CRG_CTL_EN_BIT,
|
||||
ESR_FCC_300MA | ESR_FAST_CRG_CTL_EN_BIT);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in writing to %04x, rc=%d\n",
|
||||
BATT_INFO_ESR_FAST_CRG_CFG(chip), rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
chip->esr_fcc_ctrl_en = true;
|
||||
} else {
|
||||
if (!chip->esr_fcc_ctrl_en)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If we're here, then it means either the device is not in
|
||||
* charging state or parallel charging is disabled. Disable
|
||||
* ESR fast charge current control in SW.
|
||||
*/
|
||||
rc = fg_masked_write(chip, BATT_INFO_ESR_FAST_CRG_CFG(chip),
|
||||
ESR_FAST_CRG_CTL_EN_BIT, 0);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in writing to %04x, rc=%d\n",
|
||||
BATT_INFO_ESR_FAST_CRG_CFG(chip), rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
chip->esr_fcc_ctrl_en = false;
|
||||
}
|
||||
|
||||
fg_dbg(chip, FG_STATUS, "esr_fcc_ctrl_en set to %d\n",
|
||||
chip->esr_fcc_ctrl_en);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void status_change_work(struct work_struct *work)
|
||||
{
|
||||
struct fg_chip *chip = container_of(work,
|
||||
|
@ -1428,6 +1505,10 @@ static void status_change_work(struct work_struct *work)
|
|||
rc = fg_adjust_ki_coeff_dischg(chip);
|
||||
if (rc < 0)
|
||||
pr_err("Error in adjusting ki_coeff_dischg, rc=%d\n", rc);
|
||||
|
||||
rc = fg_esr_fcc_config(chip);
|
||||
if (rc < 0)
|
||||
pr_err("Error in adjusting FCC for ESR, rc=%d\n", rc);
|
||||
out:
|
||||
pm_relax(chip->dev);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue