Merge "qcom-charger: software fix for OTG soft-start"

This commit is contained in:
Linux Build Service Account 2016-10-10 18:28:29 -07:00 committed by Gerrit - the friendly Code Review server
commit 3e53c4d76c
5 changed files with 100 additions and 4 deletions

View file

@ -53,6 +53,12 @@ Charger specific properties:
Definition: Specifies the USB input current limit in micro-amps.
If the value is not present, 1.5Amps is used as default.
- qcom,usb-ocl-ua
Usage: optional
Value type: <u32>
Definition: Specifies the OTG output current limit in micro-amps.
If the value is not present, 1.5Amps is used as default
- qcom,dc-icl-ua
Usage: optional
Value type: <u32>

View file

@ -58,6 +58,13 @@ static struct smb_params v1_params = {
.max_u = 4800000,
.step_u = 25000,
},
.otg_cl = {
.name = "usb otg current limit",
.reg = OTG_CURRENT_LIMIT_CFG_REG,
.min_u = 250000,
.max_u = 2000000,
.step_u = 250000,
},
.dc_icl = {
.name = "dc input current limit",
.reg = DCIN_CURRENT_LIMIT_CFG_REG,
@ -202,6 +209,7 @@ struct smb_dt_props {
bool no_battery;
int fcc_ua;
int usb_icl_ua;
int otg_cl_ua;
int dc_icl_ua;
int fv_uv;
int wipower_max_uw;
@ -226,6 +234,7 @@ 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)
{
struct smb_charger *chg = &chip->chg;
@ -277,6 +286,11 @@ static int smb2_parse_dt(struct smb2 *chip)
if (rc < 0)
chip->dt.usb_icl_ua = -EINVAL;
rc = of_property_read_u32(node,
"qcom,otg-cl-ua", &chip->dt.otg_cl_ua);
if (rc < 0)
chip->dt.otg_cl_ua = MICRO_1P5A;
rc = of_property_read_u32(node,
"qcom,dc-icl-ua", &chip->dt.dc_icl_ua);
if (rc < 0)
@ -981,6 +995,8 @@ static int smb2_init_hw(struct smb2 *chip)
smblib_get_charge_param(chg, &chg->param.dc_icl,
&chip->dt.dc_icl_ua);
chg->otg_cl_ua = chip->dt.otg_cl_ua;
/* votes must be cast before configuring software control */
vote(chg->pl_disable_votable,
PL_INDIRECT_VOTER, true, 0);

View file

@ -12,6 +12,7 @@
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/iio/consumer.h>
#include <linux/power_supply.h>
#include <linux/regulator/driver.h>
@ -642,6 +643,31 @@ suspend:
return rc;
}
#define MICRO_250MA 250000
static int smblib_otg_cl_config(struct smb_charger *chg, int otg_cl_ua)
{
int rc = 0;
rc = smblib_set_charge_param(chg, &chg->param.otg_cl, otg_cl_ua);
if (rc < 0) {
dev_err(chg->dev, "Couldn't set otg current limit rc=%d\n",
rc);
return rc;
}
/* configure PFM/PWM mode for OTG regulator */
rc = smblib_masked_write(chg, DC_ENG_SSUPPLY_CFG3_REG,
ENG_SSUPPLY_CFG_SKIP_TH_V0P2_BIT,
otg_cl_ua > MICRO_250MA ? 1 : 0);
if (rc < 0) {
dev_err(chg->dev,
"Couldn't write DC_ENG_SSUPPLY_CFG3_REG rc=%d\n", rc);
return rc;
}
return rc;
}
static int smblib_dc_icl_vote_callback(struct votable *votable, void *data,
int icl_ua, const char *client)
{
@ -746,14 +772,36 @@ static int smblib_pl_enable_indirect_vote_callback(struct votable *votable,
* OTG REGULATOR *
*****************/
#define OTG_SOFT_START_DELAY_MS 20
int smblib_vbus_regulator_enable(struct regulator_dev *rdev)
{
struct smb_charger *chg = rdev_get_drvdata(rdev);
u8 stat;
int rc = 0;
rc = regmap_write(chg->regmap, CMD_OTG_REG, OTG_EN_BIT);
if (rc < 0)
rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG,
ENG_BUCKBOOST_HALT1_8_MODE_BIT,
ENG_BUCKBOOST_HALT1_8_MODE_BIT);
if (rc < 0) {
dev_err(chg->dev, "Couldn't set OTG_ENG_OTG_CFG_REG rc=%d\n",
rc);
return rc;
}
rc = smblib_write(chg, CMD_OTG_REG, OTG_EN_BIT);
if (rc < 0) {
dev_err(chg->dev, "Couldn't enable OTG regulator rc=%d\n", rc);
return rc;
}
msleep(OTG_SOFT_START_DELAY_MS);
rc = smblib_read(chg, OTG_STATUS_REG, &stat);
if (rc < 0) {
dev_err(chg->dev, "Couldn't read OTG_STATUS_REG rc=%d\n", rc);
return rc;
}
if (stat & BOOST_SOFTSTART_DONE_BIT)
smblib_otg_cl_config(chg, chg->otg_cl_ua);
return rc;
}
@ -763,9 +811,22 @@ int smblib_vbus_regulator_disable(struct regulator_dev *rdev)
struct smb_charger *chg = rdev_get_drvdata(rdev);
int rc = 0;
rc = regmap_write(chg->regmap, CMD_OTG_REG, 0);
if (rc < 0)
rc = smblib_write(chg, CMD_OTG_REG, 0);
if (rc < 0) {
dev_err(chg->dev, "Couldn't disable OTG regulator rc=%d\n", rc);
return rc;
}
smblib_otg_cl_config(chg, MICRO_250MA);
rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG,
ENG_BUCKBOOST_HALT1_8_MODE_BIT, 0);
if (rc < 0) {
dev_err(chg->dev, "Couldn't set OTG_ENG_OTG_CFG_REG rc=%d\n",
rc);
return rc;
}
return rc;
}

View file

@ -77,6 +77,7 @@ struct smb_params {
struct smb_chg_param fv;
struct smb_chg_param usb_icl;
struct smb_chg_param icl_stat;
struct smb_chg_param otg_cl;
struct smb_chg_param dc_icl;
struct smb_chg_param dc_icl_pt_lv;
struct smb_chg_param dc_icl_pt_hv;
@ -167,6 +168,8 @@ struct smb_charger {
int thermal_levels;
int *thermal_mitigation;
int otg_cl_ua;
int fake_capacity;
bool step_chg_enabled;

View file

@ -366,6 +366,9 @@ enum {
#define OTG_EN_SRC_CFG_BIT BIT(1)
#define CONCURRENT_MODE_CFG_BIT BIT(0)
#define OTG_ENG_OTG_CFG_REG (OTG_BASE + 0xC0)
#define ENG_BUCKBOOST_HALT1_8_MODE_BIT BIT(0)
/* BATIF Peripheral Registers */
/* BATIF Interrupt Bits */
#define BAT_7_RT_STS_BIT BIT(7)
@ -766,6 +769,13 @@ enum {
ZIN_ICL_HV_MAX_MV = 11000,
};
#define DC_ENG_SSUPPLY_CFG3_REG (DCIN_BASE + 0xC2)
#define ENG_SSUPPLY_HI_CAP_BIT BIT(6)
#define ENG_SSUPPLY_HI_RES_BIT BIT(5)
#define ENG_SSUPPLY_CFG_SKIP_TH_V0P2_BIT BIT(3)
#define ENG_SSUPPLY_CFG_SYSOV_TH_4P8_BIT BIT(2)
#define ENG_SSUPPLY_5V_OV_OPT_BIT BIT(0)
/* MISC Peripheral Registers */
#define REVISION1_REG (MISC_BASE + 0x00)
#define DIG_MINOR_MASK GENMASK(7, 0)