qcom-charger: smb138x: fix buck damage on v1.1 hardware

Buck damage was observed because the OOB comparator activated
when HSFET was on, causing a direct short from VBUS to ground. Fix this
on V1.1 by increasing the OOB comparator threshold. On 2.0 this is fixed
by ensuring the OOB comparator activates only after HSFET minimum on
time. This in turn guarantees that HSFET and LSFET won't be on at the
same time.

Since the driver needs to detect the version of the smb, make use of the
qpnp-revid module.

CRs-Fixed: 1055113
Change-Id: I0a7946db2f1bdacf1974fb508da46f2ed4dadadc
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
Abhijeet Dharmapurikar 2016-08-16 16:32:38 -07:00
parent c5984ec85c
commit 85635da429
4 changed files with 91 additions and 0 deletions

View file

@ -24,6 +24,13 @@ Charger specific properties:
Standalone/Parallel Master - "qcom,smb138x-charger"
Parallel Slave - "qcom,smb138x-parallel-slave"
- qcom,pmic-revid
Usage: required
Value type: phandle
Definition: Should specify the phandle of SMB's
revid module. This is used to identify
the SMB subtype.
- qcom,suspend-input
Usage: optional
Value type: <empty>

View file

@ -370,8 +370,14 @@
#interrupt-cells = <3>;
qcom,periph-map = <0x10 0x11 0x12 0x13 0x14 0x16 0x36>;
smb138x_revid: qcom,revid@100 {
compatible = "qcom,qpnp-revid";
reg = <0x100 0x100>;
};
smb138x_parallel_slave: qcom,smb138x-parallel-slave@1000 {
compatible = "qcom,smb138x-parallel-slave";
qcom,pmic-revid = <&smb138x_revid>;
reg = <0x1000 0x700>;
};
};

View file

@ -22,6 +22,7 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/machine.h>
#include <linux/qpnp/qpnp-revid.h>
#include "smb-reg.h"
#include "smb-lib.h"
#include "pmic-voter.h"
@ -29,6 +30,14 @@
#define SMB138X_DEFAULT_FCC_UA 1000000
#define SMB138X_DEFAULT_ICL_UA 1500000
/* Registers that are not common to be mentioned in smb-reg.h */
#define SMB2CHG_MISC_ENG_SDCDC_CFG2 (MISC_BASE + 0xC1)
#define ENG_SDCDC_SEL_OOB_VTH_BIT BIT(0)
enum {
OOB_COMP_WA_BIT = BIT(0),
};
static struct smb_params v1_params = {
.fcc = {
.name = "fast charge current",
@ -68,6 +77,7 @@ struct smb_dt_props {
};
struct smb138x {
u32 wa_flags;
struct smb_charger chg;
struct smb_dt_props dt;
struct power_supply *parallel_psy;
@ -625,9 +635,56 @@ static int smb138x_init_hw(struct smb138x *chip)
return 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) {
dev_err(chg->dev,
"Couldn't configure the oob comp threh rc = %d\n", rc);
return rc;
}
}
return rc;
}
static int smb138x_setup_wa_flags(struct smb138x *chip)
{
struct pmic_revid_data *pmic_rev_id;
struct device_node *revid_dev_node;
revid_dev_node = of_parse_phandle(chip->chg.dev->of_node,
"qcom,pmic-revid", 0);
if (!revid_dev_node) {
pr_err("Missing qcom,pmic-revid property\n");
return -EINVAL;
}
pmic_rev_id = get_revid_data(revid_dev_node);
if (IS_ERR_OR_NULL(pmic_rev_id)) {
/*
* the revid peripheral must be registered, any failure
* here only indicates that the rev-id module has not
* probed yet.
*/
return -EPROBE_DEFER;
}
switch (pmic_rev_id->pmic_subtype) {
case SMB1381_SUBTYPE:
if (pmic_rev_id->rev4 < 2) /* SMB1381 rev 1.0 */
chip->wa_flags |= OOB_COMP_WA_BIT;
break;
default:
pr_err("PMIC subtype %d not supported\n",
pmic_rev_id->pmic_subtype);
return -EINVAL;
}
return 0;
}
/****************************
* DETERMINE INITIAL STATUS *
****************************/
@ -857,6 +914,17 @@ static int smb138x_slave_probe(struct smb138x *chip)
return 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) {
dev_err(chg->dev,
"Couldn't configure the oob comp threh rc = %d\n", rc);
return rc;
}
}
/* suspend usb input */
rc = smblib_set_usb_suspend(chg, true);
if (rc < 0) {
@ -938,6 +1006,13 @@ static int smb138x_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, chip);
rc = smb138x_setup_wa_flags(chip);
if (rc < 0) {
if (rc != -EPROBE_DEFER)
pr_err("Couldn't setup wa flags rc = %d\n", rc);
return rc;
}
chip->chg.mode = (enum smb_mode) id->data;
switch (chip->chg.mode) {
case PARALLEL_MASTER:

View file

@ -201,6 +201,9 @@
/* PMI8937 */
#define PMI8937_SUBTYPE 0x37
/* SMB1381 */
#define SMB1381_SUBTYPE 0x17
struct pmic_revid_data {
u8 rev1;
u8 rev2;