power: qcom-charger: add support for USBIN-USBIN parallel configuration
Add support for USBIN-USBIN configuration based parallel charging. This involves splitting Input Current Limit(ICL) between the main and the parallel charger, ICL re-split is done when the settled AICL of the main charger changes by 300mA. Change-Id: I5b916f1503a2267ca1e73b24096cb60a304e3c19 Signed-off-by: Ashay Jaiswal <ashayj@codeaurora.org> Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
parent
23d22ee4bf
commit
504aeb1158
4 changed files with 37 additions and 10 deletions
|
@ -2,7 +2,7 @@ obj-$(CONFIG_QPNP_SMBCHARGER) += qpnp-smbcharger.o batterydata-lib.o pmic-voter.
|
|||
obj-$(CONFIG_QPNP_FG) += qpnp-fg.o
|
||||
obj-$(CONFIG_QPNP_FG_GEN3) += qpnp-fg-gen3.o fg-memif.o fg-util.o
|
||||
obj-$(CONFIG_SMB135X_CHARGER) += smb135x-charger.o pmic-voter.o
|
||||
obj-$(CONFIG_SMB1351_USB_CHARGER) += smb1351-charger.o pmic-voter.o
|
||||
obj-$(CONFIG_SMB1351_USB_CHARGER) += smb1351-charger.o pmic-voter.o battery.o
|
||||
obj-$(CONFIG_MSM_BCL_CTL) += msm_bcl.o
|
||||
obj-$(CONFIG_MSM_BCL_PERIPHERAL_CTL) += bcl_peripheral.o
|
||||
obj-$(CONFIG_BATTERY_BCL) += battery_current_limit.o
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#define PL_TAPER_EARLY_BAD_VOTER "PL_TAPER_EARLY_BAD_VOTER"
|
||||
#define PARALLEL_PSY_VOTER "PARALLEL_PSY_VOTER"
|
||||
#define PL_HW_ABSENT_VOTER "PL_HW_ABSENT_VOTER"
|
||||
#define PL_VOTER "PL_VOTER"
|
||||
|
||||
struct pl_data {
|
||||
int pl_mode;
|
||||
|
@ -50,8 +51,9 @@ struct pl_data {
|
|||
struct power_supply *main_psy;
|
||||
struct power_supply *pl_psy;
|
||||
struct power_supply *batt_psy;
|
||||
int settled_ua;
|
||||
int charge_type;
|
||||
int main_settled_ua;
|
||||
int pl_settled_ua;
|
||||
struct class qcom_batt_class;
|
||||
struct wakeup_source *pl_ws;
|
||||
struct notifier_block nb;
|
||||
|
@ -85,7 +87,7 @@ enum {
|
|||
static void split_settled(struct pl_data *chip)
|
||||
{
|
||||
int slave_icl_pct;
|
||||
int slave_ua = 0;
|
||||
int slave_ua = 0, main_settled_ua = 0;
|
||||
union power_supply_propval pval = {0, };
|
||||
int rc;
|
||||
|
||||
|
@ -108,10 +110,11 @@ static void split_settled(struct pl_data *chip)
|
|||
pr_err("Couldn't get aicl settled value rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
chip->settled_ua = pval.intval;
|
||||
main_settled_ua = pval.intval;
|
||||
/* slave gets 10 percent points less for ICL */
|
||||
slave_icl_pct = max(0, chip->slave_pct - 10);
|
||||
slave_ua = (chip->settled_ua * slave_icl_pct) / 100;
|
||||
slave_ua = ((main_settled_ua + chip->pl_settled_ua)
|
||||
* slave_icl_pct) / 100;
|
||||
}
|
||||
|
||||
/* ICL_REDUCTION on main could be 0mA when pl is disabled */
|
||||
|
@ -131,6 +134,11 @@ static void split_settled(struct pl_data *chip)
|
|||
pr_err("Couldn't set parallel icl, rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* main_settled_ua represents the total capability of adapter */
|
||||
if (!chip->main_settled_ua)
|
||||
chip->main_settled_ua = main_settled_ua;
|
||||
chip->pl_settled_ua = slave_ua;
|
||||
}
|
||||
|
||||
static ssize_t version_show(struct class *c, struct class_attribute *attr,
|
||||
|
@ -379,8 +387,9 @@ static int pl_disable_vote_callback(struct votable *votable,
|
|||
union power_supply_propval pval = {0, };
|
||||
int rc;
|
||||
|
||||
chip->settled_ua = 0;
|
||||
chip->taper_pct = 100;
|
||||
chip->main_settled_ua = 0;
|
||||
chip->pl_settled_ua = 0;
|
||||
|
||||
if (!pl_disable) { /* enable */
|
||||
rc = power_supply_get_property(chip->pl_psy,
|
||||
|
@ -561,6 +570,7 @@ static void handle_main_charge_type(struct pl_data *chip)
|
|||
chip->charge_type = pval.intval;
|
||||
}
|
||||
|
||||
#define MIN_ICL_CHANGE_DELTA_UA 300000
|
||||
static void handle_settled_aicl_split(struct pl_data *chip)
|
||||
{
|
||||
union power_supply_propval pval = {0, };
|
||||
|
@ -579,10 +589,11 @@ static void handle_settled_aicl_split(struct pl_data *chip)
|
|||
pr_err("Couldn't get aicl settled value rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
if (chip->settled_ua != pval.intval) {
|
||||
chip->settled_ua = pval.intval;
|
||||
|
||||
/* If ICL change is small skip splitting */
|
||||
if (abs((chip->main_settled_ua - chip->pl_settled_ua)
|
||||
- pval.intval) > MIN_ICL_CHANGE_DELTA_UA)
|
||||
split_settled(chip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1380,6 +1380,18 @@ static int smb2_init_hw(struct smb2 *chip)
|
|||
vote(chg->hvdcp_enable_votable, MICRO_USB_VOTER,
|
||||
chg->micro_usb_mode, 0);
|
||||
|
||||
/*
|
||||
* AICL configuration:
|
||||
* start from min and AICL ADC disable
|
||||
*/
|
||||
rc = smblib_masked_write(chg, USBIN_AICL_OPTIONS_CFG_REG,
|
||||
USBIN_AICL_START_AT_MAX_BIT
|
||||
| USBIN_AICL_ADC_EN_BIT, 0);
|
||||
if (rc < 0) {
|
||||
dev_err(chg->dev, "Couldn't configure AICL rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Configure charge enable for software control; active high */
|
||||
rc = smblib_masked_write(chg, CHGR_CFG2_REG,
|
||||
CHG_EN_POLARITY_BIT |
|
||||
|
|
|
@ -774,13 +774,17 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data,
|
|||
if (chg->usb_psy_desc.type != POWER_SUPPLY_TYPE_USB) {
|
||||
if (client) {
|
||||
rc = smblib_set_charge_param(chg, &chg->param.usb_icl,
|
||||
icl_ua);
|
||||
icl_ua - chg->icl_reduction_ua);
|
||||
if (rc < 0) {
|
||||
smblib_err(chg, "Couldn't set HC ICL rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
smblib_dbg(chg, PR_PARALLEL,
|
||||
"icl_ua=%d icl_reduction=%d\n",
|
||||
icl_ua, chg->icl_reduction_ua);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue