diff options
| -rw-r--r-- | drivers/power/supply/qcom/battery.c | 41 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/qpnp-smb2.c | 7 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.c | 57 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.h | 1 |
4 files changed, 70 insertions, 36 deletions
diff --git a/drivers/power/supply/qcom/battery.c b/drivers/power/supply/qcom/battery.c index 0c80c8be7909..99a5f48ad5db 100644 --- a/drivers/power/supply/qcom/battery.c +++ b/drivers/power/supply/qcom/battery.c @@ -49,6 +49,7 @@ struct pl_data { struct votable *pl_disable_votable; struct votable *pl_awake_votable; struct votable *hvdcp_hw_inov_dis_votable; + struct votable *usb_icl_votable; struct work_struct status_change_work; struct work_struct pl_disable_forever_work; struct delayed_work pl_taper_work; @@ -487,6 +488,25 @@ static int pl_fv_vote_callback(struct votable *votable, void *data, return 0; } +static int usb_icl_vote_callback(struct votable *votable, void *data, + int icl_ua, const char *client) +{ + struct pl_data *chip = data; + union power_supply_propval pval = {0, }; + + if (!chip->main_psy) + return 0; + + if (client == NULL) + icl_ua = INT_MAX; + + pval.intval = icl_ua; + return power_supply_set_property(chip->main_psy, + POWER_SUPPLY_PROP_INPUT_CURRENT_MAX, &pval); + + return 0; +} + static void pl_disable_forever_work(struct work_struct *work) { struct pl_data *chip = container_of(work, @@ -596,13 +616,15 @@ static int pl_awake_vote_callback(struct votable *votable, static bool is_main_available(struct pl_data *chip) { - if (!chip->main_psy) - chip->main_psy = power_supply_get_by_name("main"); + if (chip->main_psy) + return true; - if (!chip->main_psy) - return false; + chip->main_psy = power_supply_get_by_name("main"); - return true; + if (chip->main_psy) + rerun_election(chip->usb_icl_votable); + + return !!chip->main_psy; } static bool is_batt_available(struct pl_data *chip) @@ -855,6 +877,14 @@ static int pl_init(void) goto destroy_votable; } + chip->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN, + usb_icl_vote_callback, + chip); + if (IS_ERR(chip->usb_icl_votable)) { + rc = PTR_ERR(chip->usb_icl_votable); + goto destroy_votable; + } + chip->pl_disable_votable = create_votable("PL_DISABLE", VOTE_SET_ANY, pl_disable_vote_callback, chip); @@ -909,6 +939,7 @@ destroy_votable: destroy_votable(chip->pl_disable_votable); destroy_votable(chip->fv_votable); destroy_votable(chip->fcc_votable); + destroy_votable(chip->usb_icl_votable); release_wakeup_source: wakeup_source_unregister(chip->pl_ws); cleanup: diff --git a/drivers/power/supply/qcom/qpnp-smb2.c b/drivers/power/supply/qcom/qpnp-smb2.c index 0a0f1decf65e..77e21a7976ff 100644 --- a/drivers/power/supply/qcom/qpnp-smb2.c +++ b/drivers/power/supply/qcom/qpnp-smb2.c @@ -616,6 +616,7 @@ static enum power_supply_property smb2_usb_main_props[] = { POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, POWER_SUPPLY_PROP_FCC_DELTA, + POWER_SUPPLY_PROP_CURRENT_MAX, /* * TODO move the TEMP and TEMP_MAX properties here, * and update the thermal balancer to look here @@ -653,6 +654,9 @@ static int smb2_usb_main_get_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_FCC_DELTA: rc = smblib_get_prop_fcc_delta(chg, val); break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + val->intval = get_effective_result(chg->usb_icl_votable); + break; default: pr_debug("get prop %d is not supported in usb-main\n", psp); rc = -EINVAL; @@ -683,6 +687,9 @@ static int smb2_usb_main_set_prop(struct power_supply *psy, case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval); break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + rc = smblib_set_icl_current(chg, val->intval); + break; default: pr_err("set prop %d is not supported\n", psp); rc = -EINVAL; diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c index 8c7665ea381b..5e1300ce1897 100644 --- a/drivers/power/supply/qcom/smb-lib.c +++ b/drivers/power/supply/qcom/smb-lib.c @@ -798,29 +798,12 @@ static int smblib_get_pulse_cnt(struct smb_charger *chg, int *count) return 0; } -/********************* - * VOTABLE CALLBACKS * - *********************/ - -static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, - int suspend, const char *client) -{ - struct smb_charger *chg = data; - - /* resume input if suspend is invalid */ - if (suspend < 0) - suspend = 0; - - return smblib_set_dc_suspend(chg, (bool)suspend); -} - #define USBIN_25MA 25000 #define USBIN_100MA 100000 #define USBIN_150MA 150000 #define USBIN_500MA 500000 #define USBIN_900MA 900000 - static int set_sdp_current(struct smb_charger *chg, int icl_ua) { int rc; @@ -859,20 +842,18 @@ static int set_sdp_current(struct smb_charger *chg, int icl_ua) return rc; } -static int smblib_usb_icl_vote_callback(struct votable *votable, void *data, - int icl_ua, const char *client) +int smblib_set_icl_current(struct smb_charger *chg, int icl_ua) { - struct smb_charger *chg = data; int rc = 0; bool override; union power_supply_propval pval; /* suspend and return if 25mA or less is requested */ - if (client && (icl_ua < USBIN_25MA)) + if (icl_ua < USBIN_25MA) return smblib_set_usb_suspend(chg, true); disable_irq_nosync(chg->irq_info[USBIN_ICL_CHANGE_IRQ].irq); - if (!client) + if (icl_ua == INT_MAX) goto override_suspend_config; rc = smblib_get_prop_typec_mode(chg, &pval); @@ -901,7 +882,7 @@ static int smblib_usb_icl_vote_callback(struct votable *votable, void *data, override_suspend_config: /* determine if override needs to be enforced */ override = true; - if (client == NULL) { + if (icl_ua == INT_MAX) { /* remove override if no voters - hw defaults is desired */ override = false; } else if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { @@ -939,6 +920,22 @@ enable_icl_changed_interrupt: return rc; } +/********************* + * VOTABLE CALLBACKS * + *********************/ + +static int smblib_dc_suspend_vote_callback(struct votable *votable, void *data, + int suspend, const char *client) +{ + struct smb_charger *chg = data; + + /* resume input if suspend is invalid */ + if (suspend < 0) + suspend = 0; + + return smblib_set_dc_suspend(chg, (bool)suspend); +} + static int smblib_dc_icl_vote_callback(struct votable *votable, void *data, int icl_ua, const char *client) { @@ -4217,6 +4214,12 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } + chg->usb_icl_votable = find_votable("USB_ICL"); + if (!chg->usb_icl_votable) { + rc = -EPROBE_DEFER; + return rc; + } + chg->pl_disable_votable = find_votable("PL_DISABLE"); if (!chg->pl_disable_votable) { rc = -EPROBE_DEFER; @@ -4233,14 +4236,6 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } - chg->usb_icl_votable = create_votable("USB_ICL", VOTE_MIN, - smblib_usb_icl_vote_callback, - chg); - if (IS_ERR(chg->usb_icl_votable)) { - rc = PTR_ERR(chg->usb_icl_votable); - return rc; - } - chg->dc_icl_votable = create_votable("DC_ICL", VOTE_MIN, smblib_dc_icl_vote_callback, chg); diff --git a/drivers/power/supply/qcom/smb-lib.h b/drivers/power/supply/qcom/smb-lib.h index e3ab3d555dd0..2b09a5bbd1a1 100644 --- a/drivers/power/supply/qcom/smb-lib.h +++ b/drivers/power/supply/qcom/smb-lib.h @@ -492,6 +492,7 @@ 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_set_icl_current(struct smb_charger *chg, int icl_ua); int smblib_init(struct smb_charger *chg); int smblib_deinit(struct smb_charger *chg); |
