summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshay Jaiswal <ashayj@codeaurora.org>2017-02-17 16:00:05 +0530
committerAshay Jaiswal <ashayj@codeaurora.org>2017-02-18 09:41:34 +0530
commit58ca30db67041303f4b0fc619f36585c0405401d (patch)
tree2f050cae3743b5fd14fc4cc445216409e88552d3
parentfb2e7e98695e4bfb60f57a94465952e0dcdd0d77 (diff)
power: qcom-charger: add support for internal and external rsense
USBIN-USBIN parallel configuration can have either an internal current sensing via main charger's BATFET or an external current sense resistor. The FCC split between main and parallel charger differs based on current sensing mode, add support to differentiate internal/external sensing and the FCC split is done as follows: - Internal Sensing: Main charger configure to full FCC Parallel charger configured to 50% FCC. - External sensing: Main charger configure to 50% FCC Parallel charger configured to 50% FCC. Change-Id: Ia0c6234ce6f62af460edd3c4f56e34810899b3e3 Signed-off-by: Ashay Jaiswal <ashayj@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/power/supply/qcom/smb1351-charger.txt2
-rw-r--r--drivers/power/supply/qcom/battery.c28
-rw-r--r--drivers/power/supply/qcom/smb1351-charger.c9
-rw-r--r--drivers/power/supply/qcom/smb138x-charger.c2
-rw-r--r--include/linux/power_supply.h7
5 files changed, 35 insertions, 13 deletions
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/smb1351-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb1351-charger.txt
index ab0ac32e444e..c200f9423384 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/smb1351-charger.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/smb1351-charger.txt
@@ -69,6 +69,8 @@ Optional Properties:
via pin in a parallel-charger configuration.
0 - Active low and 1 - Active high.
If not specified the default value is active-low.
+- qcom,parallel-external-current-sense If present specifies external rsense is
+ used for charge current sensing.
Example for standalone charger:
diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c
index 35dc3842017b..5fcc4244d2a0 100644
--- a/drivers/power/supply/qcom/battery.c
+++ b/drivers/power/supply/qcom/battery.c
@@ -96,7 +96,8 @@ static void split_settled(struct pl_data *chip)
* for desired split
*/
- if (chip->pl_mode != POWER_SUPPLY_PARALLEL_USBIN_USBIN)
+ if ((chip->pl_mode != POWER_SUPPLY_PL_USBIN_USBIN)
+ && (chip->pl_mode != POWER_SUPPLY_PL_USBIN_USBIN_EXT))
return;
if (!chip->main_psy)
@@ -262,7 +263,7 @@ static void split_fcc(struct pl_data *chip, int total_ua,
hw_cc_delta_ua = pval.intval;
bcl_ua = INT_MAX;
- if (chip->pl_mode == POWER_SUPPLY_PARALLEL_MID_MID) {
+ if (chip->pl_mode == POWER_SUPPLY_PL_USBMID_USBMID) {
rc = power_supply_get_property(chip->main_psy,
POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval);
if (rc < 0) {
@@ -287,7 +288,15 @@ static void split_fcc(struct pl_data *chip, int total_ua,
slave_limited_ua = min(effective_total_ua, bcl_ua);
*slave_ua = (slave_limited_ua * chip->slave_pct) / 100;
*slave_ua = (*slave_ua * chip->taper_pct) / 100;
- *master_ua = max(0, total_ua - *slave_ua);
+ /*
+ * In USBIN_USBIN configuration with internal rsense parallel
+ * charger's current goes through main charger's BATFET, keep
+ * the main charger's FCC to the votable result.
+ */
+ if (chip->pl_mode == POWER_SUPPLY_PL_USBIN_USBIN)
+ *master_ua = max(0, total_ua);
+ else
+ *master_ua = max(0, total_ua - *slave_ua);
}
static int pl_fcc_vote_callback(struct votable *votable, void *data,
@@ -316,7 +325,7 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data,
total_fcc_ua = pval.intval;
}
- if (chip->pl_mode == POWER_SUPPLY_PARALLEL_NONE
+ if (chip->pl_mode == POWER_SUPPLY_PL_NONE
|| get_effective_result_locked(chip->pl_disable_votable)) {
pval.intval = total_fcc_ua;
rc = power_supply_set_property(chip->main_psy,
@@ -391,7 +400,7 @@ static int pl_fv_vote_callback(struct votable *votable, void *data,
return rc;
}
- if (chip->pl_mode != POWER_SUPPLY_PARALLEL_NONE) {
+ if (chip->pl_mode != POWER_SUPPLY_PL_NONE) {
pval.intval += PARALLEL_FLOAT_VOLTAGE_DELTA_UV;
rc = power_supply_set_property(chip->pl_psy,
POWER_SUPPLY_PROP_VOLTAGE_MAX, &pval);
@@ -451,7 +460,8 @@ static int pl_disable_vote_callback(struct votable *votable,
pr_err("Couldn't change slave suspend state rc=%d\n",
rc);
- if (chip->pl_mode == POWER_SUPPLY_PARALLEL_USBIN_USBIN)
+ if ((chip->pl_mode == POWER_SUPPLY_PL_USBIN_USBIN)
+ || (chip->pl_mode == POWER_SUPPLY_PL_USBIN_USBIN_EXT))
split_settled(chip);
/*
* we could have been enabled while in taper mode,
@@ -469,7 +479,8 @@ static int pl_disable_vote_callback(struct votable *votable,
}
}
} else {
- if (chip->pl_mode == POWER_SUPPLY_PARALLEL_USBIN_USBIN)
+ if ((chip->pl_mode == POWER_SUPPLY_PL_USBIN_USBIN)
+ || (chip->pl_mode == POWER_SUPPLY_PL_USBIN_USBIN_EXT))
split_settled(chip);
/* pl_psy may be NULL while in the disable branch */
@@ -610,7 +621,8 @@ static void handle_settled_aicl_split(struct pl_data *chip)
int rc;
if (!get_effective_result(chip->pl_disable_votable)
- && chip->pl_mode == POWER_SUPPLY_PARALLEL_USBIN_USBIN) {
+ && (chip->pl_mode == POWER_SUPPLY_PL_USBIN_USBIN
+ || chip->pl_mode == POWER_SUPPLY_PL_USBIN_USBIN_EXT)) {
/*
* call aicl split only when USBIN_USBIN and enabled
* and if aicl changed
diff --git a/drivers/power/supply/qcom/smb1351-charger.c b/drivers/power/supply/qcom/smb1351-charger.c
index d0cf37b0613a..8467d167512f 100644
--- a/drivers/power/supply/qcom/smb1351-charger.c
+++ b/drivers/power/supply/qcom/smb1351-charger.c
@@ -460,6 +460,7 @@ struct smb1351_charger {
int workaround_flags;
int parallel_pin_polarity_setting;
+ int parallel_mode;
bool parallel_charger;
bool parallel_charger_suspended;
bool bms_controlled_charging;
@@ -1699,7 +1700,7 @@ static int smb1351_parallel_get_property(struct power_supply *psy,
val->intval = 0;
break;
case POWER_SUPPLY_PROP_PARALLEL_MODE:
- val->intval = POWER_SUPPLY_PARALLEL_USBIN_USBIN;
+ val->intval = chip->parallel_mode;
break;
default:
return -EINVAL;
@@ -3191,6 +3192,12 @@ static int smb1351_parallel_charger_probe(struct i2c_client *client,
chip->parallel_pin_polarity_setting ?
EN_BY_PIN_HIGH_ENABLE : EN_BY_PIN_LOW_ENABLE;
+ if (of_property_read_bool(node,
+ "qcom,parallel-external-current-sense"))
+ chip->parallel_mode = POWER_SUPPLY_PL_USBIN_USBIN_EXT;
+ else
+ chip->parallel_mode = POWER_SUPPLY_PL_USBIN_USBIN;
+
i2c_set_clientdata(client, chip);
chip->parallel_psy_d.name = "parallel";
diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c
index 4180edc89a4c..6af9ce1c16df 100644
--- a/drivers/power/supply/qcom/smb138x-charger.c
+++ b/drivers/power/supply/qcom/smb138x-charger.c
@@ -493,7 +493,7 @@ static int smb138x_parallel_get_prop(struct power_supply *psy,
val->strval = "smb138x";
break;
case POWER_SUPPLY_PROP_PARALLEL_MODE:
- val->intval = POWER_SUPPLY_PARALLEL_MID_MID;
+ val->intval = POWER_SUPPLY_PL_USBMID_USBMID;
break;
case POWER_SUPPLY_PROP_CONNECTOR_HEALTH:
rc = smblib_get_prop_die_health(chg, val);
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index 457d862cb9a8..1effc355d7d0 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -106,9 +106,10 @@ enum {
};
enum {
- POWER_SUPPLY_PARALLEL_NONE,
- POWER_SUPPLY_PARALLEL_USBIN_USBIN,
- POWER_SUPPLY_PARALLEL_MID_MID,
+ POWER_SUPPLY_PL_NONE,
+ POWER_SUPPLY_PL_USBIN_USBIN,
+ POWER_SUPPLY_PL_USBIN_USBIN_EXT,
+ POWER_SUPPLY_PL_USBMID_USBMID,
};
enum power_supply_property {