summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhijeet Dharmapurikar <adharmap@codeaurora.org>2016-10-14 10:55:42 -0700
committerNicholas Troast <ntroast@codeaurora.org>2016-10-17 13:56:25 -0700
commit2bfdf681777b64587cac011bc4a8bac979d7e38d (patch)
treec9ea60a03b4d8a88135bee449955c027af362023
parentc7e2ce5a8c92f4cf5017a654c64282a2005a3cfc (diff)
smb-lib: qpnp-smb2: cleanup parallel charging code
The parallel charging code has grown organically. Clean up the following: 1. Use correct units for all unit based variables. 2. Use slave percent instead of master percent. 3. Remove parallel master module parameter. 4. Put PARALLEL_DISABLE where it belongs in battery psy. 5. Create a get_jeita_cc_delta function similar to get_step_cc_delta function. 6. Print errors when returning error codes. Change-Id: I27ec29c3a6c5f3aac31705e60e1b8cf3270322a1 Signed-off-by: Nicholas Troast <ntroast@codeaurora.org> Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
-rw-r--r--drivers/power/qcom-charger/qpnp-smb2.c25
-rw-r--r--drivers/power/qcom-charger/smb-lib.c143
-rw-r--r--drivers/power/qcom-charger/smb-lib.h6
-rw-r--r--drivers/power/qcom-charger/smb-reg.h1
4 files changed, 90 insertions, 85 deletions
diff --git a/drivers/power/qcom-charger/qpnp-smb2.c b/drivers/power/qcom-charger/qpnp-smb2.c
index 954a03f042f7..b1264719b32a 100644
--- a/drivers/power/qcom-charger/qpnp-smb2.c
+++ b/drivers/power/qcom-charger/qpnp-smb2.c
@@ -233,11 +233,6 @@ module_param_named(
debug_mask, __debug_mask, int, S_IRUSR | S_IWUSR
);
-static int __pl_master_percent = 50;
-module_param_named(
- pl_master_percent, __pl_master_percent, int, S_IRUSR | S_IWUSR
-);
-
#define MICRO_1P5A 1500000
static int smb2_parse_dt(struct smb2 *chip)
{
@@ -356,7 +351,6 @@ static enum power_supply_property smb2_usb_props[] = {
POWER_SUPPLY_PROP_PD_ACTIVE,
POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
POWER_SUPPLY_PROP_INPUT_CURRENT_NOW,
- POWER_SUPPLY_PROP_PARALLEL_DISABLE,
};
static int smb2_usb_get_prop(struct power_supply *psy,
@@ -422,10 +416,6 @@ static int smb2_usb_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_INPUT_CURRENT_NOW:
rc = smblib_get_prop_usb_current_now(chg, val);
break;
- case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
- val->intval = get_client_vote(chg->pl_disable_votable,
- USER_VOTER);
- break;
case POWER_SUPPLY_PROP_PD_IN_HARD_RESET:
rc = smblib_get_prop_pd_in_hard_reset(chg, val);
break;
@@ -471,9 +461,6 @@ static int smb2_usb_set_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_PD_ACTIVE:
rc = smblib_set_prop_pd_active(chg, val);
break;
- case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
- vote(chg->pl_disable_votable, USER_VOTER, (bool)val->intval, 0);
- break;
case POWER_SUPPLY_PROP_PD_IN_HARD_RESET:
rc = smblib_set_prop_pd_in_hard_reset(chg, val);
break;
@@ -494,7 +481,6 @@ static int smb2_usb_prop_is_writeable(struct power_supply *psy,
{
switch (psp) {
case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
- case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
return 1;
default:
break;
@@ -653,6 +639,7 @@ static enum power_supply_property smb2_batt_props[] = {
POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED,
POWER_SUPPLY_PROP_STEP_CHARGING_STEP,
POWER_SUPPLY_PROP_CHARGE_DONE,
+ POWER_SUPPLY_PROP_PARALLEL_DISABLE,
};
static int smb2_batt_get_prop(struct power_supply *psy,
@@ -713,6 +700,10 @@ static int smb2_batt_get_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_CHARGE_DONE:
rc = smblib_get_prop_batt_charge_done(chg, val);
break;
+ case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
+ val->intval = get_client_vote(chg->pl_disable_votable,
+ USER_VOTER);
+ break;
default:
pr_err("batt power supply prop %d not supported\n", psp);
return -EINVAL;
@@ -743,6 +734,9 @@ static int smb2_batt_set_prop(struct power_supply *psy,
case POWER_SUPPLY_PROP_CAPACITY:
rc = smblib_set_prop_batt_capacity(chg, val);
break;
+ case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
+ vote(chg->pl_disable_votable, USER_VOTER, (bool)val->intval, 0);
+ break;
default:
rc = -EINVAL;
}
@@ -757,6 +751,7 @@ static int smb2_batt_prop_is_writeable(struct power_supply *psy,
case POWER_SUPPLY_PROP_INPUT_SUSPEND:
case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
case POWER_SUPPLY_PROP_CAPACITY:
+ case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
return 1;
default:
break;
@@ -1585,7 +1580,6 @@ static int smb2_probe(struct platform_device *pdev)
chg->debug_mask = &__debug_mask;
chg->mode = PARALLEL_MASTER;
chg->name = "PMI";
- chg->pl.master_percent = &__pl_master_percent;
chg->regmap = dev_get_regmap(chg->dev->parent, NULL);
if (!chg->regmap) {
@@ -1654,6 +1648,7 @@ static int smb2_probe(struct platform_device *pdev)
return 0;
}
+ chg->pl.slave_pct = 50;
rc = smb2_init_batt_psy(chip);
if (rc < 0) {
pr_err("Couldn't initialize batt psy rc=%d\n", rc);
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c
index c719773fae30..1bd60e547327 100644
--- a/drivers/power/qcom-charger/smb-lib.c
+++ b/drivers/power/qcom-charger/smb-lib.c
@@ -91,15 +91,13 @@ unlock:
return rc;
}
-static int smblib_get_step_charging_adjustment(struct smb_charger *chg,
- int *cc_offset)
+static int smblib_get_step_cc_delta(struct smb_charger *chg, int *cc_delta_ua)
{
- int step_state;
- int rc;
+ int rc, step_state;
u8 stat;
if (!chg->step_chg_enabled) {
- *cc_offset = 0;
+ *cc_delta_ua = 0;
return 0;
}
@@ -113,57 +111,70 @@ static int smblib_get_step_charging_adjustment(struct smb_charger *chg,
step_state = (stat & STEP_CHARGING_STATUS_MASK) >>
STEP_CHARGING_STATUS_SHIFT;
rc = smblib_get_charge_param(chg, &chg->param.step_cc_delta[step_state],
- cc_offset);
+ cc_delta_ua);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't get step cc delta rc=%d\n", rc);
+ return rc;
+ }
- return rc;
+ return 0;
}
-static void smblib_fcc_split_ua(struct smb_charger *chg, int total_fcc,
- int *master_ua, int *slave_ua)
+static int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua)
{
- int rc, cc_reduction_ua = 0;
- int step_cc_delta;
- int master_percent = min(max(*chg->pl.master_percent, 0), 100);
- union power_supply_propval pval = {0, };
- int effective_fcc;
+ int rc, cc_minus_ua;
+ u8 stat;
- /*
- * if master_percent is 0, s/w will configure master's fcc to zero and
- * slave's fcc to the max. However since master's fcc is zero it
- * disables its own charging and as a result the slave's charging is
- * disabled via the fault line.
- */
+ rc = smblib_read(chg, BATTERY_CHARGER_STATUS_2_REG, &stat);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't read BATTERY_CHARGER_STATUS_2 rc=%d\n",
+ rc);
+ return rc;
+ }
- rc = smblib_get_prop_batt_health(chg, &pval);
- if (rc == 0) {
- if (pval.intval == POWER_SUPPLY_HEALTH_WARM
- || pval.intval == POWER_SUPPLY_HEALTH_COOL) {
- rc = smblib_get_charge_param(chg,
- &chg->param.jeita_cc_comp,
- &cc_reduction_ua);
- if (rc < 0) {
- smblib_err(chg, "Could not get jeita comp, rc=%d\n",
- rc);
- cc_reduction_ua = 0;
- }
- }
+ if (!(stat & BAT_TEMP_STATUS_SOFT_LIMIT_MASK)) {
+ *cc_delta_ua = 0;
+ return 0;
}
- rc = smblib_get_step_charging_adjustment(chg, &step_cc_delta);
- if (rc < 0)
- step_cc_delta = 0;
+ rc = smblib_get_charge_param(chg, &chg->param.jeita_cc_comp,
+ &cc_minus_ua);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't get jeita cc minus rc=%d\n", rc);
+ return rc;
+ }
- /*
- * During JEITA condition and with step_charging enabled, PMI will
- * pick the lower of the two value: (FCC - JEITA current compensation)
- * or (FCC + step_charging current delta)
- */
+ *cc_delta_ua = -cc_minus_ua;
+ return 0;
+}
- effective_fcc = min(max(0, total_fcc - cc_reduction_ua),
- max(0, total_fcc + step_cc_delta));
- *master_ua = (effective_fcc * master_percent) / 100;
- *slave_ua = (effective_fcc - *master_ua) * chg->pl.taper_percent / 100;
- *master_ua = max(0, *master_ua + total_fcc - effective_fcc);
+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;
+
+ rc = smblib_get_step_cc_delta(chg, &step_cc_delta_ua);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't get step cc delta rc=%d\n", rc);
+ step_cc_delta_ua = 0;
+ } else {
+ hw_cc_delta_ua = step_cc_delta_ua;
+ }
+
+ rc = smblib_get_jeita_cc_delta(chg, &jeita_cc_delta_ua);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't get jeita cc delta rc=%d\n", rc);
+ jeita_cc_delta_ua = 0;
+ } else if (jeita_cc_delta_ua < 0) {
+ /* HW will take the min between JEITA and step charge */
+ hw_cc_delta_ua = min(hw_cc_delta_ua, jeita_cc_delta_ua);
+ }
+
+ effective_total_ua = max(0, total_ua + hw_cc_delta_ua);
+ *slave_ua = (effective_total_ua * chg->pl.slave_pct) / 100;
+ *slave_ua = (*slave_ua * chg->pl.taper_pct) / 100;
+ *master_ua = max(0, total_ua - *slave_ua);
}
/********************
@@ -577,27 +588,25 @@ static int smblib_fcc_max_vote_callback(struct votable *votable, void *data,
}
static int smblib_fcc_vote_callback(struct votable *votable, void *data,
- int fcc_ua, const char *client)
+ int total_fcc_ua, const char *client)
{
struct smb_charger *chg = data;
- int rc = 0;
union power_supply_propval pval = {0, };
- int master_ua = fcc_ua, slave_ua;
+ int rc, master_fcc_ua = total_fcc_ua, slave_fcc_ua;
- if (fcc_ua < 0) {
- smblib_dbg(chg, PR_MISC, "No Voter\n");
+ if (total_fcc_ua < 0)
return 0;
- }
if (chg->mode == PARALLEL_MASTER
&& !get_effective_result_locked(chg->pl_disable_votable)) {
- smblib_fcc_split_ua(chg, fcc_ua, &master_ua, &slave_ua);
+ smblib_split_fcc(chg, total_fcc_ua, &master_fcc_ua,
+ &slave_fcc_ua);
/*
* parallel charger is not disabled, implying that
* chg->pl.psy exists
*/
- pval.intval = slave_ua;
+ pval.intval = slave_fcc_ua;
rc = power_supply_set_property(chg->pl.psy,
POWER_SUPPLY_PROP_CURRENT_MAX, &pval);
if (rc < 0) {
@@ -606,12 +615,12 @@ static int smblib_fcc_vote_callback(struct votable *votable, void *data,
return rc;
}
- chg->pl.slave_fcc = slave_ua;
+ chg->pl.slave_fcc_ua = slave_fcc_ua;
}
- rc = smblib_set_charge_param(chg, &chg->param.fcc, master_ua);
+ rc = smblib_set_charge_param(chg, &chg->param.fcc, master_fcc_ua);
if (rc < 0) {
- smblib_err(chg, "Error in setting fcc, rc=%d\n", rc);
+ smblib_err(chg, "Couldn't set master fcc rc=%d\n", rc);
return rc;
}
@@ -811,7 +820,7 @@ static int smblib_pl_disable_vote_callback(struct votable *votable, void *data,
if (chg->mode != PARALLEL_MASTER || !chg->pl.psy)
return 0;
- chg->pl.taper_percent = 100;
+ chg->pl.taper_pct = 100;
rerun_election(chg->fv_votable);
rerun_election(chg->fcc_votable);
@@ -2177,15 +2186,15 @@ skip_dpdm_float:
return IRQ_HANDLED;
}
-#define USB_WEAK_INPUT_MA 1400000
+#define USB_WEAK_INPUT_UA 1400000
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 icl_ma;
- int rc;
+ int rc, icl_ua;
+
- rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &icl_ma);
+ rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &icl_ua);
if (rc < 0) {
smblib_err(chg, "Couldn't get ICL status rc=%d\n", rc);
return IRQ_HANDLED;
@@ -2193,7 +2202,7 @@ irqreturn_t smblib_handle_icl_change(int irq, void *data)
if (chg->mode == PARALLEL_MASTER)
vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER,
- icl_ma >= USB_WEAK_INPUT_MA, 0);
+ icl_ua >= USB_WEAK_INPUT_UA, 0);
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s\n", irq_data->name);
@@ -2569,7 +2578,7 @@ static void smblib_pl_detect_work(struct work_struct *work)
#define MINIMUM_PARALLEL_FCC_UA 500000
#define PL_TAPER_WORK_DELAY_MS 100
-#define TAPER_RESIDUAL_PERCENT 75
+#define TAPER_RESIDUAL_PCT 75
static void smblib_pl_taper_work(struct work_struct *work)
{
struct smb_charger *chg = container_of(work, struct smb_charger,
@@ -2577,7 +2586,7 @@ static void smblib_pl_taper_work(struct work_struct *work)
union power_supply_propval pval = {0, };
int rc;
- if (chg->pl.slave_fcc < MINIMUM_PARALLEL_FCC_UA) {
+ if (chg->pl.slave_fcc_ua < MINIMUM_PARALLEL_FCC_UA) {
vote(chg->pl_disable_votable, TAPER_END_VOTER, true, 0);
goto done;
}
@@ -2591,8 +2600,8 @@ static void smblib_pl_taper_work(struct work_struct *work)
if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) {
vote(chg->awake_votable, PL_TAPER_WORK_RUNNING_VOTER, true, 0);
/* Reduce the taper percent by 25 percent */
- chg->pl.taper_percent = chg->pl.taper_percent
- * TAPER_RESIDUAL_PERCENT / 100;
+ chg->pl.taper_pct = chg->pl.taper_pct
+ * TAPER_RESIDUAL_PCT / 100;
rerun_election(chg->fcc_votable);
schedule_delayed_work(&chg->pl_taper_work,
msecs_to_jiffies(PL_TAPER_WORK_DELAY_MS));
diff --git a/drivers/power/qcom-charger/smb-lib.h b/drivers/power/qcom-charger/smb-lib.h
index b6913fa12f1a..2bc5255568e6 100644
--- a/drivers/power/qcom-charger/smb-lib.h
+++ b/drivers/power/qcom-charger/smb-lib.h
@@ -102,9 +102,9 @@ struct smb_params {
struct parallel_params {
struct power_supply *psy;
- int *master_percent;
- int taper_percent;
- int slave_fcc;
+ int slave_pct;
+ int taper_pct;
+ int slave_fcc_ua;
};
struct smb_iio {
diff --git a/drivers/power/qcom-charger/smb-reg.h b/drivers/power/qcom-charger/smb-reg.h
index c2941f61f4a2..ba501761c209 100644
--- a/drivers/power/qcom-charger/smb-reg.h
+++ b/drivers/power/qcom-charger/smb-reg.h
@@ -52,6 +52,7 @@ enum {
#define CHARGER_ERROR_STATUS_BAT_OV_BIT BIT(5)
#define CHARGER_ERROR_STATUS_BAT_TERM_MISSING_BIT BIT(4)
#define BAT_TEMP_STATUS_MASK GENMASK(3, 0)
+#define BAT_TEMP_STATUS_SOFT_LIMIT_MASK GENMASK(3, 2)
#define BAT_TEMP_STATUS_HOT_SOFT_LIMIT_BIT BIT(3)
#define BAT_TEMP_STATUS_COLD_SOFT_LIMIT_BIT BIT(2)
#define BAT_TEMP_STATUS_TOO_HOT_BIT BIT(1)