diff options
Diffstat (limited to 'drivers/power/qcom-charger/smb-lib.c')
| -rw-r--r-- | drivers/power/qcom-charger/smb-lib.c | 162 |
1 files changed, 145 insertions, 17 deletions
diff --git a/drivers/power/qcom-charger/smb-lib.c b/drivers/power/qcom-charger/smb-lib.c index dd3ec1eb51e3..8fe882e078f0 100644 --- a/drivers/power/qcom-charger/smb-lib.c +++ b/drivers/power/qcom-charger/smb-lib.c @@ -210,22 +210,6 @@ static const struct apsd_result *smblib_get_apsd_result(struct smb_charger *chg) * REGISTER SETTERS * ********************/ -int smblib_enable_charging(struct smb_charger *chg, bool enable) -{ - int rc = 0; - - rc = smblib_masked_write(chg, CHARGING_ENABLE_CMD_REG, - CHARGING_ENABLE_CMD_BIT, - enable ? CHARGING_ENABLE_CMD_BIT : 0); - if (rc < 0) { - dev_err(chg->dev, "Couldn't %s charging rc=%d\n", - enable ? "enable" : "disable", rc); - return rc; - } - - return rc; -} - int smblib_set_charge_param(struct smb_charger *chg, struct smb_chg_param *param, int val_u) { @@ -416,6 +400,14 @@ static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, return smblib_set_dc_suspend(chg, suspend); } +static int smblib_fcc_max_vote_callback(struct votable *votable, void *data, + int fcc_ua, const char *client) +{ + struct smb_charger *chg = data; + + return vote(chg->fcc_votable, FCC_MAX_RESULT, true, fcc_ua); +} + static int smblib_fcc_vote_callback(struct votable *votable, void *data, int fcc_ua, const char *client) { @@ -606,6 +598,23 @@ static int smblib_pl_disable_vote_callback(struct votable *votable, void *data, return 0; } +static int smblib_chg_disable_vote_callback(struct votable *votable, void *data, + int chg_disable, const char *client) +{ + struct smb_charger *chg = data; + int rc; + + rc = smblib_masked_write(chg, CHARGING_ENABLE_CMD_REG, + CHARGING_ENABLE_CMD_BIT, + chg_disable ? 0 : CHARGING_ENABLE_CMD_BIT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't %s charging rc=%d\n", + chg_disable ? "disable" : "enable", rc); + return rc; + } + + return 0; +} /***************** * OTG REGULATOR * *****************/ @@ -849,6 +858,13 @@ done: return rc; } +int smblib_get_prop_system_temp_level(struct smb_charger *chg, + union power_supply_propval *val) +{ + val->intval = chg->system_temp_level; + return 0; +} + /*********************** * BATTERY PSY SETTERS * ***********************/ @@ -876,6 +892,101 @@ int smblib_set_prop_input_suspend(struct smb_charger *chg, return rc; } +int smblib_set_prop_system_temp_level(struct smb_charger *chg, + const union power_supply_propval *val) +{ + if (val->intval < 0) + return -EINVAL; + + if (chg->thermal_levels <= 0) + return -EINVAL; + + if (val->intval > chg->thermal_levels) + return -EINVAL; + + chg->system_temp_level = val->intval; + if (chg->system_temp_level == chg->thermal_levels) + return vote(chg->chg_disable_votable, THERMAL_DAEMON, true, 0); + + vote(chg->chg_disable_votable, THERMAL_DAEMON, false, 0); + if (chg->system_temp_level == 0) + return vote(chg->fcc_votable, THERMAL_DAEMON, false, 0); + + vote(chg->fcc_votable, THERMAL_DAEMON, true, + chg->thermal_mitigation[chg->system_temp_level]); + return 0; +} + +/******************* + * DC PSY GETTERS * + *******************/ + +int smblib_get_prop_dc_present(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc = 0; + u8 stat; + + rc = smblib_read(chg, DC_INT_RT_STS_REG, &stat); + if (rc < 0) { + dev_err(chg->dev, "Couldn't read DC_INT_RT_STS_REG rc=%d\n", + rc); + return rc; + } + smblib_dbg(chg, PR_REGISTER, "DC_INT_RT_STS_REG = 0x%02x\n", + stat); + + val->intval = (bool)(stat & DCIN_PLUGIN_RT_STS_BIT); + + return rc; +} + +int smblib_get_prop_dc_online(struct smb_charger *chg, + union power_supply_propval *val) +{ + int rc = 0; + u8 stat; + + if (get_client_vote(chg->dc_suspend_votable, USER_VOTER)) { + val->intval = false; + return rc; + } + + rc = smblib_read(chg, POWER_PATH_STATUS_REG, &stat); + if (rc < 0) { + dev_err(chg->dev, "Couldn't read POWER_PATH_STATUS rc=%d\n", + rc); + return rc; + } + smblib_dbg(chg, PR_REGISTER, "POWER_PATH_STATUS = 0x%02x\n", + stat); + + val->intval = (stat & USE_DCIN_BIT) && + (stat & VALID_INPUT_POWER_SOURCE_BIT); + + return rc; +} + +int smblib_get_prop_dc_current_max(struct smb_charger *chg, + union power_supply_propval *val) +{ + val->intval = get_effective_result_locked(chg->dc_icl_votable); + return 0; +} + +/******************* + * USB PSY SETTERS * + * *****************/ + +int smblib_set_prop_dc_current_max(struct smb_charger *chg, + const union power_supply_propval *val) +{ + int rc; + + rc = vote(chg->dc_icl_votable, USER_VOTER, true, val->intval); + return rc; +} + /******************* * USB PSY GETTERS * *******************/ @@ -1694,7 +1805,15 @@ int smblib_create_votables(struct smb_charger *chg) return rc; } - chg->fcc_votable = create_votable("FCC", VOTE_MAX, + chg->fcc_max_votable = create_votable("FCC_MAX", VOTE_MAX, + smblib_fcc_max_vote_callback, + chg); + if (IS_ERR(chg->fcc_max_votable)) { + rc = PTR_ERR(chg->fcc_max_votable); + return rc; + } + + chg->fcc_votable = create_votable("FCC", VOTE_MIN, smblib_fcc_vote_callback, chg); if (IS_ERR(chg->fcc_votable)) { @@ -1749,6 +1868,14 @@ int smblib_create_votables(struct smb_charger *chg) return rc; } + chg->chg_disable_votable = create_votable("CHG_DISABLE", VOTE_SET_ANY, + smblib_chg_disable_vote_callback, + chg); + if (IS_ERR(chg->chg_disable_votable)) { + rc = PTR_ERR(chg->chg_disable_votable); + return rc; + } + return rc; } @@ -1796,6 +1923,7 @@ int smblib_deinit(struct smb_charger *chg) { destroy_votable(chg->usb_suspend_votable); destroy_votable(chg->dc_suspend_votable); + destroy_votable(chg->fcc_max_votable); destroy_votable(chg->fcc_votable); destroy_votable(chg->fv_votable); destroy_votable(chg->usb_icl_votable); |
