Merge "power: qcom-charger: delay ICL change reporting to parallel psy"
This commit is contained in:
commit
e7d1ccb3fa
9 changed files with 308 additions and 30 deletions
|
@ -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:
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ struct pl_data {
|
|||
struct votable *fv_votable;
|
||||
struct votable *pl_disable_votable;
|
||||
struct votable *pl_awake_votable;
|
||||
struct votable *hvdcp_hw_inov_dis_votable;
|
||||
struct work_struct status_change_work;
|
||||
struct work_struct pl_disable_forever_work;
|
||||
struct delayed_work pl_taper_work;
|
||||
|
@ -96,7 +97,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 +264,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,6 +289,14 @@ 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;
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
@ -316,7 +326,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 +401,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);
|
||||
|
@ -411,6 +421,10 @@ static void pl_disable_forever_work(struct work_struct *work)
|
|||
|
||||
/* Disable Parallel charger forever */
|
||||
vote(chip->pl_disable_votable, PL_HW_ABSENT_VOTER, true, 0);
|
||||
|
||||
/* Re-enable autonomous mode */
|
||||
if (chip->hvdcp_hw_inov_dis_votable)
|
||||
vote(chip->hvdcp_hw_inov_dis_votable, PL_VOTER, false, 0);
|
||||
}
|
||||
|
||||
static int pl_disable_vote_callback(struct votable *votable,
|
||||
|
@ -451,7 +465,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 +484,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 */
|
||||
|
@ -552,6 +568,21 @@ static bool is_parallel_available(struct pl_data *chip)
|
|||
* pl_psy is present and valid.
|
||||
*/
|
||||
chip->pl_mode = pval.intval;
|
||||
|
||||
/* Disable autonomous votage increments for USBIN-USBIN */
|
||||
if ((chip->pl_mode == POWER_SUPPLY_PL_USBIN_USBIN)
|
||||
|| (chip->pl_mode == POWER_SUPPLY_PL_USBIN_USBIN_EXT)) {
|
||||
if (!chip->hvdcp_hw_inov_dis_votable)
|
||||
chip->hvdcp_hw_inov_dis_votable =
|
||||
find_votable("HVDCP_HW_INOV_DIS");
|
||||
if (chip->hvdcp_hw_inov_dis_votable)
|
||||
/* Read current pulse count */
|
||||
vote(chip->hvdcp_hw_inov_dis_votable, PL_VOTER,
|
||||
true, 0);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
vote(chip->pl_disable_votable, PARALLEL_PSY_VOTER, false, 0);
|
||||
|
||||
return true;
|
||||
|
@ -610,7 +641,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
|
||||
|
|
|
@ -848,6 +848,8 @@ static enum power_supply_property smb2_batt_props[] = {
|
|||
POWER_SUPPLY_PROP_PARALLEL_DISABLE,
|
||||
POWER_SUPPLY_PROP_SET_SHIP_MODE,
|
||||
POWER_SUPPLY_PROP_DIE_HEALTH,
|
||||
POWER_SUPPLY_PROP_RERUN_AICL,
|
||||
POWER_SUPPLY_PROP_DP_DM,
|
||||
};
|
||||
|
||||
static int smb2_batt_get_prop(struct power_supply *psy,
|
||||
|
@ -933,6 +935,12 @@ static int smb2_batt_get_prop(struct power_supply *psy,
|
|||
case POWER_SUPPLY_PROP_DIE_HEALTH:
|
||||
rc = smblib_get_prop_die_health(chg, val);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_DP_DM:
|
||||
val->intval = chg->pulse_cnt;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_RERUN_AICL:
|
||||
val->intval = 0;
|
||||
break;
|
||||
default:
|
||||
pr_err("batt power supply prop %d not supported\n", psp);
|
||||
return -EINVAL;
|
||||
|
@ -986,6 +994,12 @@ static int smb2_batt_set_prop(struct power_supply *psy,
|
|||
break;
|
||||
rc = smblib_set_prop_ship_mode(chg, val);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_RERUN_AICL:
|
||||
rc = smblib_rerun_aicl(chg);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_DP_DM:
|
||||
rc = smblib_dp_dm(chg, val->intval);
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
@ -1001,6 +1015,8 @@ static int smb2_batt_prop_is_writeable(struct power_supply *psy,
|
|||
case POWER_SUPPLY_PROP_SYSTEM_TEMP_LEVEL:
|
||||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
case POWER_SUPPLY_PROP_PARALLEL_DISABLE:
|
||||
case POWER_SUPPLY_PROP_DP_DM:
|
||||
case POWER_SUPPLY_PROP_RERUN_AICL:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -58,6 +58,12 @@ int smblib_read(struct smb_charger *chg, u16 addr, u8 *val)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int smblib_multibyte_read(struct smb_charger *chg, u16 addr, u8 *val,
|
||||
int count)
|
||||
{
|
||||
return regmap_bulk_read(chg->regmap, addr, val, count);
|
||||
}
|
||||
|
||||
int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -652,6 +658,8 @@ static void smblib_uusb_removal(struct smb_charger *chg)
|
|||
|
||||
chg->voltage_min_uv = MICRO_5V;
|
||||
chg->voltage_max_uv = MICRO_5V;
|
||||
chg->usb_icl_delta_ua = 0;
|
||||
chg->pulse_cnt = 0;
|
||||
|
||||
/* clear USB ICL vote for USB_PSY_VOTER */
|
||||
rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0);
|
||||
|
@ -741,6 +749,40 @@ int smblib_rerun_apsd_if_required(struct smb_charger *chg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int smblib_get_pulse_cnt(struct smb_charger *chg, int *count)
|
||||
{
|
||||
int rc;
|
||||
u8 val[2];
|
||||
|
||||
switch (chg->smb_version) {
|
||||
case PMI8998_SUBTYPE:
|
||||
rc = smblib_read(chg, QC_PULSE_COUNT_STATUS_REG, val);
|
||||
if (rc) {
|
||||
pr_err("failed to read QC_PULSE_COUNT_STATUS_REG rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
*count = val[0] & QC_PULSE_COUNT_MASK;
|
||||
break;
|
||||
case PM660_SUBTYPE:
|
||||
rc = smblib_multibyte_read(chg,
|
||||
QC_PULSE_COUNT_STATUS_1_REG, val, 2);
|
||||
if (rc) {
|
||||
pr_err("failed to read QC_PULSE_COUNT_STATUS_1_REG rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
*count = (val[1] << 8) | val[0];
|
||||
break;
|
||||
default:
|
||||
smblib_dbg(chg, PR_PARALLEL, "unknown SMB chip %d\n",
|
||||
chg->smb_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************
|
||||
* VOTABLE CALLBACKS *
|
||||
*********************/
|
||||
|
@ -975,8 +1017,10 @@ static int smblib_hvdcp_enable_vote_callback(struct votable *votable,
|
|||
{
|
||||
struct smb_charger *chg = data;
|
||||
int rc;
|
||||
u8 val = HVDCP_AUTH_ALG_EN_CFG_BIT
|
||||
| HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT | HVDCP_EN_BIT;
|
||||
u8 val = HVDCP_AUTH_ALG_EN_CFG_BIT | HVDCP_EN_BIT;
|
||||
|
||||
/* vote to enable/disable HW autonomous INOV */
|
||||
vote(chg->hvdcp_hw_inov_dis_votable, client, !hvdcp_enable, 0);
|
||||
|
||||
/*
|
||||
* Disable the autonomous bit and auth bit for disabling hvdcp.
|
||||
|
@ -987,9 +1031,7 @@ static int smblib_hvdcp_enable_vote_callback(struct votable *votable,
|
|||
val = HVDCP_EN_BIT;
|
||||
|
||||
rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG,
|
||||
HVDCP_EN_BIT
|
||||
| HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT
|
||||
| HVDCP_AUTH_ALG_EN_CFG_BIT,
|
||||
HVDCP_EN_BIT | HVDCP_AUTH_ALG_EN_CFG_BIT,
|
||||
val);
|
||||
if (rc < 0) {
|
||||
smblib_err(chg, "Couldn't %s hvdcp rc=%d\n",
|
||||
|
@ -1058,6 +1100,37 @@ static int smblib_apsd_disable_vote_callback(struct votable *votable,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int smblib_hvdcp_hw_inov_dis_vote_callback(struct votable *votable,
|
||||
void *data, int disable, const char *client)
|
||||
{
|
||||
struct smb_charger *chg = data;
|
||||
int rc;
|
||||
|
||||
if (disable) {
|
||||
/*
|
||||
* the pulse count register get zeroed when autonomous mode is
|
||||
* disabled. Track that in variables before disabling
|
||||
*/
|
||||
rc = smblib_get_pulse_cnt(chg, &chg->pulse_cnt);
|
||||
if (rc < 0) {
|
||||
pr_err("failed to read QC_PULSE_COUNT_STATUS_REG rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
rc = smblib_masked_write(chg, USBIN_OPTIONS_1_CFG_REG,
|
||||
HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT,
|
||||
disable ? 0 : HVDCP_AUTONOMOUS_MODE_EN_CFG_BIT);
|
||||
if (rc < 0) {
|
||||
smblib_err(chg, "Couldn't %s hvdcp rc=%d\n",
|
||||
disable ? "disable" : "enable", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*******************
|
||||
* VCONN REGULATOR *
|
||||
* *****************/
|
||||
|
@ -1645,6 +1718,98 @@ int smblib_set_prop_system_temp_level(struct smb_charger *chg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int smblib_rerun_aicl(struct smb_charger *chg)
|
||||
{
|
||||
int rc = 0;
|
||||
u8 val;
|
||||
|
||||
/*
|
||||
* Use restart_AICL instead of trigger_AICL as it runs the
|
||||
* complete AICL instead of starting from the last settled value.
|
||||
*
|
||||
* 8998 only supports trigger_AICL return error for 8998
|
||||
*/
|
||||
switch (chg->smb_version) {
|
||||
case PMI8998_SUBTYPE:
|
||||
smblib_dbg(chg, PR_PARALLEL, "AICL rerun not supported\n");
|
||||
return -EINVAL;
|
||||
case PM660_SUBTYPE:
|
||||
val = RESTART_AICL_BIT;
|
||||
break;
|
||||
default:
|
||||
smblib_dbg(chg, PR_PARALLEL, "unknown SMB chip %d\n",
|
||||
chg->smb_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
rc = smblib_masked_write(chg, CMD_HVDCP_2_REG, val, val);
|
||||
if (rc < 0)
|
||||
smblib_err(chg, "Couldn't write to CMD_HVDCP_2_REG rc=%d\n",
|
||||
rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int smblib_dp_pulse(struct smb_charger *chg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* QC 3.0 increment */
|
||||
rc = smblib_masked_write(chg, CMD_HVDCP_2_REG, SINGLE_INCREMENT_BIT,
|
||||
SINGLE_INCREMENT_BIT);
|
||||
if (rc < 0)
|
||||
smblib_err(chg, "Couldn't write to CMD_HVDCP_2_REG rc=%d\n",
|
||||
rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int smblib_dm_pulse(struct smb_charger *chg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* QC 3.0 decrement */
|
||||
rc = smblib_masked_write(chg, CMD_HVDCP_2_REG, SINGLE_DECREMENT_BIT,
|
||||
SINGLE_DECREMENT_BIT);
|
||||
if (rc < 0)
|
||||
smblib_err(chg, "Couldn't write to CMD_HVDCP_2_REG rc=%d\n",
|
||||
rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int smblib_dp_dm(struct smb_charger *chg, int val)
|
||||
{
|
||||
int target_icl_ua, rc = 0;
|
||||
|
||||
switch (val) {
|
||||
case POWER_SUPPLY_DP_DM_DP_PULSE:
|
||||
rc = smblib_dp_pulse(chg);
|
||||
if (!rc)
|
||||
chg->pulse_cnt++;
|
||||
smblib_dbg(chg, PR_PARALLEL, "DP_DM_DP_PULSE rc=%d cnt=%d\n",
|
||||
rc, chg->pulse_cnt);
|
||||
break;
|
||||
case POWER_SUPPLY_DP_DM_DM_PULSE:
|
||||
rc = smblib_dm_pulse(chg);
|
||||
if (!rc && chg->pulse_cnt)
|
||||
chg->pulse_cnt--;
|
||||
smblib_dbg(chg, PR_PARALLEL, "DP_DM_DM_PULSE rc=%d cnt=%d\n",
|
||||
rc, chg->pulse_cnt);
|
||||
break;
|
||||
case POWER_SUPPLY_DP_DM_ICL_DOWN:
|
||||
chg->usb_icl_delta_ua -= 100000;
|
||||
target_icl_ua = get_effective_result(chg->usb_icl_votable);
|
||||
vote(chg->usb_icl_votable, SW_QC3_VOTER, true,
|
||||
target_icl_ua + chg->usb_icl_delta_ua);
|
||||
break;
|
||||
case POWER_SUPPLY_DP_DM_ICL_UP:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*******************
|
||||
* DC PSY GETTERS *
|
||||
*******************/
|
||||
|
@ -2915,26 +3080,38 @@ irqreturn_t smblib_handle_usb_plugin(int irq, void *data)
|
|||
}
|
||||
|
||||
#define USB_WEAK_INPUT_UA 1400000
|
||||
#define ICL_CHANGE_DELAY_MS 1000
|
||||
irqreturn_t smblib_handle_icl_change(int irq, void *data)
|
||||
{
|
||||
u8 stat;
|
||||
int rc, settled_ua, delay = ICL_CHANGE_DELAY_MS;
|
||||
struct smb_irq_data *irq_data = data;
|
||||
struct smb_charger *chg = irq_data->parent_data;
|
||||
int rc, settled_ua;
|
||||
|
||||
rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &settled_ua);
|
||||
if (chg->mode == PARALLEL_MASTER) {
|
||||
rc = smblib_read(chg, AICL_STATUS_REG, &stat);
|
||||
if (rc < 0) {
|
||||
smblib_err(chg, "Couldn't read AICL_STATUS rc=%d\n",
|
||||
rc);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
rc = smblib_get_charge_param(chg, &chg->param.icl_stat,
|
||||
&settled_ua);
|
||||
if (rc < 0) {
|
||||
smblib_err(chg, "Couldn't get ICL status rc=%d\n", rc);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
if (chg->mode == PARALLEL_MASTER) {
|
||||
power_supply_changed(chg->usb_main_psy);
|
||||
vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER,
|
||||
settled_ua >= USB_WEAK_INPUT_UA, 0);
|
||||
/* If AICL settled then schedule work now */
|
||||
if ((settled_ua == get_effective_result(chg->usb_icl_votable))
|
||||
|| (stat & AICL_DONE_BIT))
|
||||
delay = 0;
|
||||
|
||||
schedule_delayed_work(&chg->icl_change_work,
|
||||
msecs_to_jiffies(delay));
|
||||
}
|
||||
|
||||
smblib_dbg(chg, PR_INTERRUPT, "IRQ: %s icl_settled=%d\n",
|
||||
irq_data->name, settled_ua);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -3279,6 +3456,8 @@ static void smblib_handle_typec_removal(struct smb_charger *chg)
|
|||
|
||||
chg->vconn_attempts = 0;
|
||||
chg->otg_attempts = 0;
|
||||
chg->pulse_cnt = 0;
|
||||
chg->usb_icl_delta_ua = 0;
|
||||
|
||||
chg->usb_ever_removed = true;
|
||||
|
||||
|
@ -3801,6 +3980,25 @@ static void smblib_otg_ss_done_work(struct work_struct *work)
|
|||
mutex_unlock(&chg->otg_oc_lock);
|
||||
}
|
||||
|
||||
static void smblib_icl_change_work(struct work_struct *work)
|
||||
{
|
||||
struct smb_charger *chg = container_of(work, struct smb_charger,
|
||||
icl_change_work.work);
|
||||
int rc, settled_ua;
|
||||
|
||||
rc = smblib_get_charge_param(chg, &chg->param.icl_stat, &settled_ua);
|
||||
if (rc < 0) {
|
||||
smblib_err(chg, "Couldn't get ICL status rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
power_supply_changed(chg->usb_main_psy);
|
||||
vote(chg->pl_enable_votable_indirect, USBIN_I_VOTER,
|
||||
settled_ua >= USB_WEAK_INPUT_UA, 0);
|
||||
|
||||
smblib_dbg(chg, PR_INTERRUPT, "icl_settled=%d\n", settled_ua);
|
||||
}
|
||||
|
||||
static int smblib_create_votables(struct smb_charger *chg)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -3917,6 +4115,15 @@ static int smblib_create_votables(struct smb_charger *chg)
|
|||
return rc;
|
||||
}
|
||||
|
||||
chg->hvdcp_hw_inov_dis_votable = create_votable("HVDCP_HW_INOV_DIS",
|
||||
VOTE_SET_ANY,
|
||||
smblib_hvdcp_hw_inov_dis_vote_callback,
|
||||
chg);
|
||||
if (IS_ERR(chg->hvdcp_hw_inov_dis_votable)) {
|
||||
rc = PTR_ERR(chg->hvdcp_hw_inov_dis_votable);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -3940,6 +4147,8 @@ static void smblib_destroy_votables(struct smb_charger *chg)
|
|||
destroy_votable(chg->pl_enable_votable_indirect);
|
||||
if (chg->apsd_disable_votable)
|
||||
destroy_votable(chg->apsd_disable_votable);
|
||||
if (chg->hvdcp_hw_inov_dis_votable)
|
||||
destroy_votable(chg->hvdcp_hw_inov_dis_votable);
|
||||
}
|
||||
|
||||
static void smblib_iio_deinit(struct smb_charger *chg)
|
||||
|
@ -3970,6 +4179,7 @@ int smblib_init(struct smb_charger *chg)
|
|||
INIT_WORK(&chg->otg_oc_work, smblib_otg_oc_work);
|
||||
INIT_WORK(&chg->vconn_oc_work, smblib_vconn_oc_work);
|
||||
INIT_DELAYED_WORK(&chg->otg_ss_done_work, smblib_otg_ss_done_work);
|
||||
INIT_DELAYED_WORK(&chg->icl_change_work, smblib_icl_change_work);
|
||||
chg->fake_capacity = -EINVAL;
|
||||
|
||||
switch (chg->mode) {
|
||||
|
|
|
@ -56,6 +56,7 @@ enum print_reason {
|
|||
#define PD_SUSPEND_SUPPORTED_VOTER "PD_SUSPEND_SUPPORTED_VOTER"
|
||||
#define PL_DELAY_HVDCP_VOTER "PL_DELAY_HVDCP_VOTER"
|
||||
#define CTM_VOTER "CTM_VOTER"
|
||||
#define SW_QC3_VOTER "SW_QC3_VOTER"
|
||||
|
||||
#define VCONN_MAX_ATTEMPTS 3
|
||||
#define OTG_MAX_ATTEMPTS 3
|
||||
|
@ -267,6 +268,7 @@ struct smb_charger {
|
|||
struct votable *hvdcp_disable_votable_indirect;
|
||||
struct votable *hvdcp_enable_votable;
|
||||
struct votable *apsd_disable_votable;
|
||||
struct votable *hvdcp_hw_inov_dis_votable;
|
||||
|
||||
/* work */
|
||||
struct work_struct bms_update_work;
|
||||
|
@ -278,6 +280,7 @@ struct smb_charger {
|
|||
struct work_struct otg_oc_work;
|
||||
struct work_struct vconn_oc_work;
|
||||
struct delayed_work otg_ss_done_work;
|
||||
struct delayed_work icl_change_work;
|
||||
|
||||
/* cached status */
|
||||
int voltage_min_uv;
|
||||
|
@ -315,6 +318,8 @@ struct smb_charger {
|
|||
/* qnovo */
|
||||
int qnovo_fcc_ua;
|
||||
int qnovo_fv_uv;
|
||||
int usb_icl_delta_ua;
|
||||
int pulse_cnt;
|
||||
};
|
||||
|
||||
int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
|
||||
|
@ -472,6 +477,8 @@ int smblib_get_prop_fcc_delta(struct smb_charger *chg,
|
|||
union power_supply_propval *val);
|
||||
int smblib_icl_override(struct smb_charger *chg, bool override);
|
||||
int smblib_set_icl_reduction(struct smb_charger *chg, int reduction_ua);
|
||||
int smblib_dp_dm(struct smb_charger *chg, int val);
|
||||
int smblib_rerun_aicl(struct smb_charger *chg);
|
||||
|
||||
int smblib_init(struct smb_charger *chg);
|
||||
int smblib_deinit(struct smb_charger *chg);
|
||||
|
|
|
@ -535,6 +535,8 @@ enum {
|
|||
#define USBIN_LT_3P6V_RT_STS_BIT BIT(1)
|
||||
#define USBIN_COLLAPSE_RT_STS_BIT BIT(0)
|
||||
|
||||
#define QC_PULSE_COUNT_STATUS_1_REG (USBIN_BASE + 0x30)
|
||||
|
||||
#define USBIN_CMD_IL_REG (USBIN_BASE + 0x40)
|
||||
#define BAT_2_SYS_FET_DIS_BIT BIT(1)
|
||||
#define USBIN_SUSPEND_BIT BIT(0)
|
||||
|
@ -544,6 +546,7 @@ enum {
|
|||
#define APSD_RERUN_BIT BIT(0)
|
||||
|
||||
#define CMD_HVDCP_2_REG (USBIN_BASE + 0x43)
|
||||
#define RESTART_AICL_BIT BIT(7)
|
||||
#define TRIGGER_AICL_BIT BIT(6)
|
||||
#define FORCE_12V_BIT BIT(5)
|
||||
#define FORCE_9V_BIT BIT(4)
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue