summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Troast <ntroast@codeaurora.org>2017-01-30 19:22:22 -0800
committerNicholas Troast <ntroast@codeaurora.org>2017-02-07 13:39:29 -0800
commit6611bb8976d1857c36c7bca5510cfe6623a6bfc3 (patch)
treecec56ae094f8a4aeff70c3fcda248020863384d2
parentabaead7bc3f98a125e6d272dfc4bbb5e04841902 (diff)
smb138x-charger: configure charger temperature threshold
The charger temperature threshold should be configured for thermal balancing. Add a device tree property to configure the temperature threshold. A default value will be used in the absence of this property. Change-Id: I5d64a8012a9c13c578714d91f1e7e4426cef235a Signed-off-by: Nicholas Troast <ntroast@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt6
-rw-r--r--drivers/power/supply/qcom/smb138x-charger.c235
2 files changed, 146 insertions, 95 deletions
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt
index 0244f910017a..862dd013c700 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/smb138x-charger.txt
@@ -52,6 +52,12 @@ Charger specific properties:
Value type: <u32>
Definition: Specifies the DC input current limit in micro-amps.
+- qcom,charger-temp-max-mdegc
+ Usage: optional
+ Value type: <u32>
+ Definition: Specifies the maximum charger temperature in milli-degrees
+ Celsius. If unspecified a default of 80000 will be used.
+
- io-channels
Usage: optional
Value type: List of <phandle u32>
diff --git a/drivers/power/supply/qcom/smb138x-charger.c b/drivers/power/supply/qcom/smb138x-charger.c
index ae15fef6c3a6..2d13745a02b9 100644
--- a/drivers/power/supply/qcom/smb138x-charger.c
+++ b/drivers/power/supply/qcom/smb138x-charger.c
@@ -10,18 +10,21 @@
* GNU General Public License for more details.
*/
+#define pr_fmt(fmt) "SMB138X: %s: " fmt, __func__
+
#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/regmap.h>
-#include <linux/power_supply.h>
+#include <linux/iio/consumer.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
#include <linux/regulator/driver.h>
-#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
#include <linux/qpnp/qpnp-revid.h>
#include "smb-reg.h"
#include "smb-lib.h"
@@ -89,6 +92,7 @@ struct smb_dt_props {
int fcc_ua;
int usb_icl_ua;
int dc_icl_ua;
+ int chg_temp_max_mdegc;
};
struct smb138x {
@@ -132,6 +136,12 @@ static int smb138x_parse_dt(struct smb138x *chip)
if (rc < 0)
chip->dt.dc_icl_ua = SMB138X_DEFAULT_ICL_UA;
+ rc = of_property_read_u32(node,
+ "qcom,charger-temp-max-mdegc",
+ &chip->dt.chg_temp_max_mdegc);
+ if (rc < 0)
+ chip->dt.chg_temp_max_mdegc = 80000;
+
return 0;
}
@@ -658,6 +668,108 @@ static int smb138x_init_vconn_regulator(struct smb138x *chip)
* HARDWARE INITIALIZATION *
***************************/
+static int smb138x_init_slave_hw(struct smb138x *chip)
+{
+ struct smb_charger *chg = &chip->chg;
+ int rc;
+
+ if (chip->wa_flags & OOB_COMP_WA_BIT) {
+ rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG2,
+ ENG_SDCDC_SEL_OOB_VTH_BIT,
+ ENG_SDCDC_SEL_OOB_VTH_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't configure the OOB comp threshold rc = %d\n",
+ rc);
+ return rc;
+ }
+
+ rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG6,
+ DEAD_TIME_MASK, HIGH_DEAD_TIME_MASK);
+ if (rc < 0) {
+ pr_err("Couldn't configure the sdcdc cfg 6 reg rc = %d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ /* enable watchdog bark and bite interrupts, and disable the watchdog */
+ rc = smblib_masked_write(chg, WD_CFG_REG, WDOG_TIMER_EN_BIT
+ | WDOG_TIMER_EN_ON_PLUGIN_BIT | BITE_WDOG_INT_EN_BIT
+ | BARK_WDOG_INT_EN_BIT,
+ BITE_WDOG_INT_EN_BIT | BARK_WDOG_INT_EN_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't configure the watchdog rc=%d\n", rc);
+ return rc;
+ }
+
+ /* disable charging when watchdog bites */
+ rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG,
+ BITE_WDOG_DISABLE_CHARGING_CFG_BIT,
+ BITE_WDOG_DISABLE_CHARGING_CFG_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't configure the watchdog bite rc=%d\n", rc);
+ return rc;
+ }
+
+ /* suspend parallel charging */
+ rc = smb138x_set_parallel_suspend(chip, true);
+ if (rc < 0) {
+ pr_err("Couldn't suspend parallel charging rc=%d\n", rc);
+ return rc;
+ }
+
+ /* initialize FCC to 0 */
+ rc = smblib_set_charge_param(chg, &chg->param.fcc, 0);
+ if (rc < 0) {
+ pr_err("Couldn't set 0 FCC rc=%d\n", rc);
+ return rc;
+ }
+
+ /* enable the charging path */
+ rc = smblib_masked_write(chg, CHARGING_ENABLE_CMD_REG,
+ CHARGING_ENABLE_CMD_BIT,
+ CHARGING_ENABLE_CMD_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't enable charging 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 | CHG_EN_SRC_BIT, 0);
+ if (rc < 0) {
+ pr_err("Couldn't configure charge enable source rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ /* enable parallel current sensing */
+ rc = smblib_masked_write(chg, CFG_REG,
+ VCHG_EN_CFG_BIT, VCHG_EN_CFG_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't enable parallel current sensing rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ /* enable stacked diode */
+ rc = smblib_write(chg, SMB2CHG_DC_TM_SREFGEN, STACKED_DIODE_EN_BIT);
+ if (rc < 0) {
+ pr_err("Couldn't enable stacked diode rc=%d\n", rc);
+ return rc;
+ }
+
+ /* initialize charger temperature threshold */
+ rc = iio_write_channel_processed(chg->iio.temp_max_chan,
+ chip->dt.chg_temp_max_mdegc);
+ if (rc < 0) {
+ pr_err("Couldn't set charger temp threshold rc=%d\n", rc);
+ return rc;
+ }
+
+ return 0;
+}
+
static int smb138x_init_hw(struct smb138x *chip)
{
struct smb_charger *chg = &chip->chg;
@@ -681,15 +793,14 @@ static int smb138x_init_hw(struct smb138x *chip)
rc = smblib_masked_write(chg, CHGR_CFG2_REG,
CHG_EN_POLARITY_BIT | CHG_EN_SRC_BIT, 0);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure charge enable source rc=%d\n", rc);
+ pr_err("Couldn't configure charge enable source rc=%d\n", rc);
return rc;
}
/* enable the charging path */
rc = vote(chg->chg_disable_votable, DEFAULT_VOTER, false, 0);
if (rc < 0) {
- dev_err(chg->dev, "Couldn't enable charging rc=%d\n", rc);
+ pr_err("Couldn't enable charging rc=%d\n", rc);
return rc;
}
@@ -701,8 +812,7 @@ static int smb138x_init_hw(struct smb138x *chip)
TYPEC_CCSTATE_CHANGE_INT_EN_BIT
| TYPEC_VBUS_ERROR_INT_EN_BIT);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure Type-C interrupts rc=%d\n", rc);
+ pr_err("Couldn't configure Type-C interrupts rc=%d\n", rc);
return rc;
}
@@ -711,16 +821,14 @@ static int smb138x_init_hw(struct smb138x *chip)
VCONN_EN_SRC_BIT | VCONN_EN_VALUE_BIT,
VCONN_EN_SRC_BIT);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure VCONN for SW control rc=%d\n", rc);
+ pr_err("Couldn't configure VCONN for SW control rc=%d\n", rc);
return rc;
}
/* configure VBUS for software control */
rc = smblib_masked_write(chg, OTG_CFG_REG, OTG_EN_SRC_CFG_BIT, 0);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure VBUS for SW control rc=%d\n", rc);
+ pr_err("Couldn't configure VBUS for SW control rc=%d\n", rc);
return rc;
}
@@ -728,8 +836,7 @@ static int smb138x_init_hw(struct smb138x *chip)
rc = smblib_masked_write(chg, TYPE_C_INTRPT_ENB_SOFTWARE_CTRL_REG,
TYPEC_POWER_ROLE_CMD_MASK, 0);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure power role for DRP rc=%d\n", rc);
+ pr_err("Couldn't configure power role for DRP rc=%d\n", rc);
return rc;
}
@@ -738,16 +845,16 @@ static int smb138x_init_hw(struct smb138x *chip)
ENG_SDCDC_SEL_OOB_VTH_BIT,
ENG_SDCDC_SEL_OOB_VTH_BIT);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure the oob comp threh rc = %d\n", rc);
+ pr_err("Couldn't configure the OOB comp threshold rc = %d\n",
+ rc);
return rc;
}
rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG6,
DEAD_TIME_MASK, HIGH_DEAD_TIME_MASK);
if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure the sdcdc cfg 6 reg rc = %d\n", rc);
+ pr_err("Couldn't configure the sdcdc cfg 6 reg rc = %d\n",
+ rc);
return rc;
}
}
@@ -1144,92 +1251,24 @@ static int smb138x_slave_probe(struct smb138x *chip)
goto cleanup;
}
- if (chip->wa_flags & OOB_COMP_WA_BIT) {
- rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG2,
- ENG_SDCDC_SEL_OOB_VTH_BIT,
- ENG_SDCDC_SEL_OOB_VTH_BIT);
- if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure the oob comp threh rc = %d\n", rc);
- goto cleanup;
- }
-
- rc = smblib_masked_write(chg, SMB2CHG_MISC_ENG_SDCDC_CFG6,
- DEAD_TIME_MASK, HIGH_DEAD_TIME_MASK);
- if (rc < 0) {
- dev_err(chg->dev,
- "Couldn't configure the sdcdc cfg 6 reg rc = %d\n", rc);
- goto cleanup;
- }
- }
-
- /* enable watchdog bark and bite interrupts, and disable the watchdog */
- rc = smblib_masked_write(chg, WD_CFG_REG, WDOG_TIMER_EN_BIT
- | WDOG_TIMER_EN_ON_PLUGIN_BIT | BITE_WDOG_INT_EN_BIT
- | BARK_WDOG_INT_EN_BIT,
- BITE_WDOG_INT_EN_BIT | BARK_WDOG_INT_EN_BIT);
- if (rc < 0) {
- pr_err("Couldn't configure the watchdog rc=%d\n", rc);
+ chg->iio.temp_max_chan = iio_channel_get(chg->dev, "charger_temp_max");
+ if (IS_ERR(chg->iio.temp_max_chan)) {
+ rc = PTR_ERR(chg->iio.temp_max_chan);
goto cleanup;
}
- /* disable charging when watchdog bites */
- rc = smblib_masked_write(chg, SNARL_BARK_BITE_WD_CFG_REG,
- BITE_WDOG_DISABLE_CHARGING_CFG_BIT,
- BITE_WDOG_DISABLE_CHARGING_CFG_BIT);
- if (rc < 0) {
- pr_err("Couldn't configure the watchdog bite rc=%d\n", rc);
- goto cleanup;
- }
-
- /* suspend parallel charging */
- rc = smb138x_set_parallel_suspend(chip, true);
- if (rc < 0) {
- pr_err("Couldn't suspend parallel charging rc=%d\n", rc);
- goto cleanup;
- }
-
- /* initialize FCC to 0 */
- rc = smblib_set_charge_param(chg, &chg->param.fcc, 0);
- if (rc < 0) {
- pr_err("Couldn't set 0 FCC rc=%d\n", rc);
- goto cleanup;
- }
-
- /* enable the charging path */
- rc = smblib_masked_write(chg, CHARGING_ENABLE_CMD_REG,
- CHARGING_ENABLE_CMD_BIT,
- CHARGING_ENABLE_CMD_BIT);
- if (rc < 0) {
- dev_err(chg->dev, "Couldn't enable charging rc=%d\n", rc);
- goto cleanup;
- }
-
- /* configure charge enable for software control; active high */
- rc = smblib_masked_write(chg, CHGR_CFG2_REG,
- CHG_EN_POLARITY_BIT | CHG_EN_SRC_BIT, 0);
+ rc = smb138x_parse_dt(chip);
if (rc < 0) {
- dev_err(chg->dev, "Couldn't configure charge enable source rc=%d\n",
- rc);
+ pr_err("Couldn't parse device tree rc=%d\n", rc);
goto cleanup;
}
- /* enable parallel current sensing */
- rc = smblib_masked_write(chg, CFG_REG,
- VCHG_EN_CFG_BIT, VCHG_EN_CFG_BIT);
+ rc = smb138x_init_slave_hw(chip);
if (rc < 0) {
- dev_err(chg->dev, "Couldn't enable parallel current sensing rc=%d\n",
- rc);
+ pr_err("Couldn't initialize hardware rc=%d\n", rc);
goto cleanup;
}
- /* enable stacked diode */
- rc = smblib_write(chg, SMB2CHG_DC_TM_SREFGEN, STACKED_DIODE_EN_BIT);
- if (rc < 0) {
- pr_err("Couldn't enable stacked diode rc=%d\n", rc);
- return rc;
- }
-
rc = smb138x_init_parallel_psy(chip);
if (rc < 0) {
pr_err("Couldn't initialize parallel psy rc=%d\n", rc);
@@ -1312,6 +1351,12 @@ static int smb138x_probe(struct platform_device *pdev)
goto cleanup;
}
+ if (rc < 0) {
+ if (rc != -EPROBE_DEFER)
+ pr_err("Couldn't probe SMB138X rc=%d\n", rc);
+ goto cleanup;
+ }
+
pr_info("SMB138X probed successfully mode=%d\n", chip->chg.mode);
return rc;