From 7aefaf5932edbf02469d1ff6b3b83fb55e95406d Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Mon, 10 Oct 2016 19:29:47 -0700 Subject: [PATCH 1/3] smb-lib: qpnp-smb2: fix input collapse by limiting slave FCC The parallel charger can collapse the input adapter. Impose a power limit on the slave charger by limiting the slave FCC. Change-Id: I02a3dc02911646240a1ecee41584903aab971d81 Signed-off-by: Nicholas Troast Signed-off-by: Abhijeet Dharmapurikar --- drivers/power/qcom-charger/smb-lib.c | 32 ++++++++++++++++++++++------ drivers/power/qcom-charger/smb-lib.h | 2 ++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c index 1bd60e547327..a27d0d8edc1b 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/qcom-charger/smb-lib.c @@ -152,7 +152,7 @@ static void smblib_split_fcc(struct smb_charger *chg, int total_ua, int *master_ua, int *slave_ua) { int rc, jeita_cc_delta_ua, step_cc_delta_ua, effective_total_ua, - hw_cc_delta_ua = 0; + slave_limited_ua, hw_cc_delta_ua = 0; rc = smblib_get_step_cc_delta(chg, &step_cc_delta_ua); if (rc < 0) { @@ -172,7 +172,8 @@ static void smblib_split_fcc(struct smb_charger *chg, int total_ua, } effective_total_ua = max(0, total_ua + hw_cc_delta_ua); - *slave_ua = (effective_total_ua * chg->pl.slave_pct) / 100; + slave_limited_ua = min(effective_total_ua, chg->input_limited_fcc_ua); + *slave_ua = (slave_limited_ua * chg->pl.slave_pct) / 100; *slave_ua = (*slave_ua * chg->pl.taper_pct) / 100; *master_ua = max(0, total_ua - *slave_ua); } @@ -592,7 +593,7 @@ static int smblib_fcc_vote_callback(struct votable *votable, void *data, { struct smb_charger *chg = data; union power_supply_propval pval = {0, }; - int rc, master_fcc_ua = total_fcc_ua, slave_fcc_ua; + int rc, master_fcc_ua = total_fcc_ua, slave_fcc_ua = 0; if (total_fcc_ua < 0) return 0; @@ -624,6 +625,11 @@ static int smblib_fcc_vote_callback(struct votable *votable, void *data, return rc; } + smblib_dbg(chg, PR_PARALLEL, "master_fcc=%d slave_fcc=%d distribution=(%d/%d)\n", + master_fcc_ua, slave_fcc_ua, + (master_fcc_ua * 100) / total_fcc_ua, + (slave_fcc_ua * 100) / total_fcc_ua); + return 0; } @@ -833,6 +839,9 @@ static int smblib_pl_disable_vote_callback(struct votable *votable, void *data, return rc; } + smblib_dbg(chg, PR_PARALLEL, "parallel charging %s\n", + pl_disable ? "disabled" : "enabled"); + return 0; } @@ -2187,12 +2196,14 @@ skip_dpdm_float: } #define USB_WEAK_INPUT_UA 1400000 +#define EFFICIENCY_PCT 80 irqreturn_t smblib_handle_icl_change(int irq, void *data) { struct smb_irq_data *irq_data = data; struct smb_charger *chg = irq_data->parent_data; int rc, icl_ua; + smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &icl_ua); if (rc < 0) { @@ -2200,11 +2211,18 @@ irqreturn_t smblib_handle_icl_change(int irq, void *data) return IRQ_HANDLED; } - if (chg->mode == PARALLEL_MASTER) - vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, - icl_ua >= USB_WEAK_INPUT_UA, 0); + if (chg->mode != PARALLEL_MASTER) + return IRQ_HANDLED; - smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name); + chg->input_limited_fcc_ua = div64_s64( + (s64)icl_ua * MICRO_5V * EFFICIENCY_PCT, + (s64)get_effective_result(chg->fv_votable) * 100); + + if (!get_effective_result(chg->pl_disable_votable)) + rerun_election(chg->fcc_votable); + + vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER, + icl_ua >= USB_WEAK_INPUT_UA, 0); return IRQ_HANDLED; } diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h index 2bc5255568e6..77badf6c7ec1 100644 --- a/drivers/power/qcom-charger/smb-lib.h +++ b/drivers/power/qcom-charger/smb-lib.h @@ -22,6 +22,7 @@ enum print_reason { PR_INTERRUPT = BIT(0), PR_REGISTER = BIT(1), PR_MISC = BIT(2), + PR_PARALLEL = BIT(3), }; #define DEFAULT_VOTER "DEFAULT_VOTER" @@ -190,6 +191,7 @@ struct smb_charger { bool step_chg_enabled; bool is_hdc; bool chg_done; + int input_limited_fcc_ua; /* workaround flag */ u32 wa_flags; From 9f95ba07188f49ab97f6997f9c72bd18033829ea Mon Sep 17 00:00:00 2001 From: Nicholas Troast Date: Tue, 11 Oct 2016 09:24:56 -0700 Subject: [PATCH 2/3] qpnp-smb2: expose parallel slave percentage via battery psy Expose the parallel distribution percentage and allow it to be modified. Change-Id: I0c9221c6a748aff5e8fbe889316f729155eded3e Signed-off-by: Nicholas Troast Signed-off-by: Abhijeet Dharmapurikar --- drivers/power/qcom-charger/qpnp-smb2.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c index b1264719b32a..f3b76f130cde 100644 --- a/drivers/power/qcom-charger/qpnp-smb2.c +++ b/drivers/power/qcom-charger/qpnp-smb2.c @@ -640,6 +640,7 @@ static enum power_supply_property smb2_batt_props[] = { POWER_SUPPLY_PROP_STEP_CHARGING_STEP, POWER_SUPPLY_PROP_CHARGE_DONE, POWER_SUPPLY_PROP_PARALLEL_DISABLE, + POWER_SUPPLY_PROP_PARALLEL_PERCENT, }; static int smb2_batt_get_prop(struct power_supply *psy, @@ -704,6 +705,9 @@ static int smb2_batt_get_prop(struct power_supply *psy, val->intval = get_client_vote(chg->pl_disable_votable, USER_VOTER); break; + case POWER_SUPPLY_PROP_PARALLEL_PERCENT: + val->intval = chg->pl.slave_pct; + break; default: pr_err("batt power supply prop %d not supported\n", psp); return -EINVAL; @@ -737,6 +741,12 @@ static int smb2_batt_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_PARALLEL_DISABLE: vote(chg->pl_disable_votable, USER_VOTER, (bool)val->intval, 0); break; + case POWER_SUPPLY_PROP_PARALLEL_PERCENT: + if (val->intval < 0 || val->intval > 100) + return -EINVAL; + chg->pl.slave_pct = val->intval; + rerun_election(chg->fcc_votable); + break; default: rc = -EINVAL; } @@ -752,6 +762,7 @@ static int smb2_batt_prop_is_writeable(struct power_supply *psy, case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL: case POWER_SUPPLY_PROP_CAPACITY: case POWER_SUPPLY_PROP_PARALLEL_DISABLE: + case POWER_SUPPLY_PROP_PARALLEL_PERCENT: return 1; default: break; From fa2d8c0cfae0b2130b4e19a843782e08b5745287 Mon Sep 17 00:00:00 2001 From: Harry Yang Date: Mon, 17 Oct 2016 10:37:12 -0700 Subject: [PATCH 3/3] qcom-charger: smblib: change secure address threshold Correct the secure address threshold to 0x0A since Misc peripheral has secure registers starting as early as 0x0A CRs-Fixed: 1048242 Change-Id: Id7ec03919e2fd08540cd7e677bf5e4048d73c23d Signed-off-by: Harry Yang --- drivers/power/qcom-charger/smb-lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c index a27d0d8edc1b..5f9775cc0fee 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/qcom-charger/smb-lib.c @@ -38,8 +38,8 @@ static bool is_secure(struct smb_charger *chg, int addr) { - /* assume everything above 0xC0 is secure */ - return (bool)((addr & 0xFF) >= 0xC0); + /* assume everything above 0xA0 is secure */ + return (bool)((addr & 0xFF) >= 0xA0); } int smblib_read(struct smb_charger *chg, u16 addr, u8 *val)