Loading drivers/power/supply/qcom/battery.c +63 −14 Original line number Diff line number Diff line Loading @@ -131,6 +131,11 @@ enum { RESTRICT_CHG_CURRENT, FCC_STEPPING_IN_PROGRESS, }; enum { PARALLEL_INPUT_MODE, PARALLEL_OUTPUT_MODE, }; /********* * HELPER* *********/ Loading @@ -143,23 +148,61 @@ static bool is_cp_available(struct pl_data *chip) return !!chip->cp_master_psy; } static bool cp_ilim_boost_enabled(struct pl_data *chip) static int cp_get_parallel_mode(struct pl_data *chip, int mode) { union power_supply_propval pval = {-1, }; union power_supply_propval pval = {-EINVAL, }; int rc = -EINVAL; if (is_cp_available(chip)) power_supply_get_property(chip->cp_master_psy, if (!is_cp_available(chip)) return -EINVAL; switch (mode) { case PARALLEL_INPUT_MODE: rc = power_supply_get_property(chip->cp_master_psy, POWER_SUPPLY_PROP_PARALLEL_MODE, &pval); break; case PARALLEL_OUTPUT_MODE: rc = power_supply_get_property(chip->cp_master_psy, POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); break; default: pr_err("Invalid mode request %d\n", mode); break; } if (rc < 0) pr_err("Failed to read CP topology for mode=%d rc=%d\n", mode, rc); return pval.intval == POWER_SUPPLY_PL_OUTPUT_VPH; return pval.intval; } /* * Adapter CC Mode: ILIM over-ridden explicitly, below takes no effect. * * Adapter CV mode: Configuration of ILIM for different topology is as below: * MID-VPH: * SMB1390 ILIM: independent of FCC and based on the AICL result or * PD advertised current, handled directly in SMB1390 * driver. * MID-VBAT: * SMB1390 ILIM: based on minimum of FCC portion of SMB1390 or ICL. * USBIN-VBAT: * SMB1390 ILIM: based on FCC portion of SMB1390 and independent of ICL. */ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) { if (!is_cp_available(chip)) return; if (cp_get_parallel_mode(chip, PARALLEL_OUTPUT_MODE) == POWER_SUPPLY_PL_OUTPUT_VPH) return; if (!chip->cp_ilim_votable) chip->cp_ilim_votable = find_votable("CP_ILIM"); if (!cp_ilim_boost_enabled(chip) && chip->cp_ilim_votable) if (chip->cp_ilim_votable) vote(chip->cp_ilim_votable, voter, true, ilim); } Loading Loading @@ -726,12 +769,13 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, chip->cp_disable_votable = find_votable("CP_DISABLE"); if (chip->cp_disable_votable) { if (cp_ilim_boost_enabled(chip)) { if (cp_get_parallel_mode(chip, PARALLEL_OUTPUT_MODE) == POWER_SUPPLY_PL_OUTPUT_VPH) { power_supply_get_property(chip->cp_master_psy, POWER_SUPPLY_PROP_MIN_ICL, &pval); /* * With ILIM boost feature ILIM configuration is * independent of battery FCC, disable CP if FCC/2 * With VPH output configuration ILIM is configured * independent of battery FCC, disable CP here if FCC/2 * falls below MIN_ICL supported by CP. */ if ((total_fcc_ua / 2) < pval.intval) Loading Loading @@ -926,8 +970,7 @@ static void fcc_stepper_work(struct work_struct *work) stepper_exit: chip->main_fcc_ua = main_fcc; chip->slave_fcc_ua = parallel_fcc; cp_configure_ilim(chip, FCC_VOTER, chip->main_fcc_ua / 2); cp_configure_ilim(chip, FCC_VOTER, chip->slave_fcc_ua / 2); if (reschedule_ms) { schedule_delayed_work(&chip->fcc_stepper_work, Loading Loading @@ -1044,6 +1087,9 @@ static int usb_icl_vote_callback(struct votable *votable, void *data, vote(chip->pl_disable_votable, ICL_CHANGE_VOTER, false, 0); /* Configure ILIM based on AICL result only if input mode is USBMID */ if (cp_get_parallel_mode(chip, PARALLEL_INPUT_MODE) == POWER_SUPPLY_PL_USBMID_USBMID) cp_configure_ilim(chip, ICL_CHANGE_VOTER, icl_ua); return 0; Loading Loading @@ -1087,7 +1133,7 @@ static int pl_disable_vote_callback(struct votable *votable, struct pl_data *chip = data; union power_supply_propval pval = {0, }; int master_fcc_ua = 0, total_fcc_ua = 0, slave_fcc_ua = 0; int rc = 0; int rc = 0, cp_ilim; bool disable = false; if (!is_main_available(chip)) Loading Loading @@ -1271,7 +1317,10 @@ static int pl_disable_vote_callback(struct votable *votable, /* main psy gets all share */ vote(chip->fcc_main_votable, MAIN_FCC_VOTER, true, total_fcc_ua); cp_configure_ilim(chip, FCC_VOTER, total_fcc_ua / 2); cp_ilim = total_fcc_ua - get_effective_result_locked( chip->fcc_main_votable); if (cp_ilim > 0) cp_configure_ilim(chip, FCC_VOTER, cp_ilim / 2); /* reset parallel FCC */ chip->slave_fcc_ua = 0; Loading drivers/power/supply/qcom/pmic-voter.c +77 −3 Original line number Diff line number Diff line Loading @@ -166,7 +166,7 @@ static int get_client_id(struct votable *votable, const char *client_str) static char *get_client_str(struct votable *votable, int client_id) { if (client_id == -EINVAL) if (!votable || (client_id == -EINVAL)) return NULL; return votable->client_strs[client_id]; Loading @@ -182,6 +182,38 @@ void unlock_votable(struct votable *votable) mutex_unlock(&votable->vote_lock); } /** * is_override_vote_enabled() - * is_override_vote_enabled_locked() - * The unlocked and locked variants of getting whether override vote is enabled. * @votable: the votable object * * Returns: * True if the client's vote is enabled; false otherwise. */ bool is_override_vote_enabled_locked(struct votable *votable) { if (!votable) return false; return votable->override_result != -EINVAL; } bool is_override_vote_enabled(struct votable *votable) { bool enable; if (!votable) return false; lock_votable(votable); enable = is_override_vote_enabled_locked(votable); unlock_votable(votable); return enable; } /** * is_client_vote_enabled() - * is_client_vote_enabled_locked() - Loading @@ -196,8 +228,13 @@ void unlock_votable(struct votable *votable) bool is_client_vote_enabled_locked(struct votable *votable, const char *client_str) { int client_id = get_client_id(votable, client_str); int client_id; if (!votable || !client_str) return false; client_id = get_client_id(votable, client_str); if (client_id < 0) return false; Loading @@ -208,6 +245,9 @@ bool is_client_vote_enabled(struct votable *votable, const char *client_str) { bool enabled; if (!votable || !client_str) return false; lock_votable(votable); enabled = is_client_vote_enabled_locked(votable, client_str); unlock_votable(votable); Loading @@ -228,8 +268,12 @@ bool is_client_vote_enabled(struct votable *votable, const char *client_str) */ int get_client_vote_locked(struct votable *votable, const char *client_str) { int client_id = get_client_id(votable, client_str); int client_id; if (!votable || !client_str) return -EINVAL; client_id = get_client_id(votable, client_str); if (client_id < 0) return -EINVAL; Loading @@ -244,6 +288,9 @@ int get_client_vote(struct votable *votable, const char *client_str) { int value; if (!votable || !client_str) return -EINVAL; lock_votable(votable); value = get_client_vote_locked(votable, client_str); unlock_votable(votable); Loading @@ -269,6 +316,9 @@ int get_client_vote(struct votable *votable, const char *client_str) */ int get_effective_result_locked(struct votable *votable) { if (!votable) return -EINVAL; if (votable->force_active) return votable->force_val; Loading @@ -282,6 +332,9 @@ int get_effective_result(struct votable *votable) { int value; if (!votable) return -EINVAL; lock_votable(votable); value = get_effective_result_locked(votable); unlock_votable(votable); Loading @@ -308,6 +361,9 @@ int get_effective_result(struct votable *votable) */ const char *get_effective_client_locked(struct votable *votable) { if (!votable) return NULL; if (votable->force_active) return DEBUG_FORCE_CLIENT; Loading @@ -321,6 +377,9 @@ const char *get_effective_client(struct votable *votable) { const char *client_str; if (!votable) return NULL; lock_votable(votable); client_str = get_effective_client_locked(votable); unlock_votable(votable); Loading Loading @@ -358,6 +417,9 @@ int vote(struct votable *votable, const char *client_str, bool enabled, int val) int rc = 0; bool similar_vote = false; if (!votable || !client_str) return -EINVAL; lock_votable(votable); client_id = get_client_id(votable, client_str); Loading Loading @@ -463,6 +525,9 @@ int vote_override(struct votable *votable, const char *override_client, { int rc = 0; if (!votable || !override_client) return -EINVAL; lock_votable(votable); if (votable->force_active) { votable->override_result = enabled ? val : -EINVAL; Loading Loading @@ -493,6 +558,9 @@ int rerun_election(struct votable *votable) int rc = 0; int effective_result; if (!votable) return -EINVAL; lock_votable(votable); effective_result = get_effective_result_locked(votable); if (votable->callback) Loading @@ -510,6 +578,9 @@ struct votable *find_votable(const char *name) struct votable *v; bool found = false; if (!name) return NULL; spin_lock_irqsave(&votable_list_slock, flags); if (list_empty(&votable_list)) goto out; Loading Loading @@ -642,6 +713,9 @@ struct votable *create_votable(const char *name, struct votable *votable; unsigned long flags; if (!name) return ERR_PTR(-EINVAL); votable = find_votable(name); if (votable) return ERR_PTR(-EEXIST); Loading drivers/power/supply/qcom/smb1390-charger-psy.c +41 −22 Original line number Diff line number Diff line Loading @@ -204,6 +204,7 @@ struct smb1390 { u32 max_temp_alarm_degc; u32 max_cutoff_soc; u32 pl_output_mode; u32 pl_input_mode; u32 cp_role; enum isns_mode current_capability; bool batt_soc_validated; Loading Loading @@ -994,6 +995,36 @@ static int smb1390_notifier_cb(struct notifier_block *nb, #define ILIM_NR 10 #define ILIM_DR 8 #define ILIM_FACTOR(ilim) ((ilim * ILIM_NR) / ILIM_DR) static void smb1390_configure_ilim(struct smb1390 *chip, int mode) { int rc; union power_supply_propval pval = {0, }; /* PPS adapter reply on the current advertised by the adapter */ if ((chip->pl_output_mode == POWER_SUPPLY_PL_OUTPUT_VPH) && (mode == POWER_SUPPLY_CP_PPS)) { rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_PD_CURRENT_MAX, &pval); if (rc < 0) pr_err("Couldn't get PD CURRENT MAX rc=%d\n", rc); else vote(chip->ilim_votable, ICL_VOTER, true, ILIM_FACTOR(pval.intval)); } /* QC3.0/Wireless adapter rely on the settled AICL for USBMID_USBMID */ if ((chip->pl_input_mode == POWER_SUPPLY_PL_USBMID_USBMID) && (mode == POWER_SUPPLY_CP_HVDCP3)) { rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval); if (rc < 0) pr_err("Couldn't get usb aicl rc=%d\n", rc); else vote(chip->ilim_votable, ICL_VOTER, true, pval.intval); } } static void smb1390_status_change_work(struct work_struct *work) { struct smb1390 *chip = container_of(work, struct smb1390, Loading Loading @@ -1047,28 +1078,7 @@ static void smb1390_status_change_work(struct work_struct *work) pval.intval); } else { vote(chip->ilim_votable, WIRELESS_VOTER, false, 0); if ((chip->pl_output_mode == POWER_SUPPLY_PL_OUTPUT_VPH) && (pval.intval == POWER_SUPPLY_CP_PPS)) { rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_PD_CURRENT_MAX, &pval); if (rc < 0) pr_err("Couldn't get PD CURRENT MAX rc=%d\n", rc); else vote(chip->ilim_votable, ICL_VOTER, true, ILIM_FACTOR(pval.intval)); } else { rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval); if (rc < 0) pr_err("Couldn't get usb aicl rc=%d\n", rc); else vote(chip->ilim_votable, ICL_VOTER, true, pval.intval); } smb1390_configure_ilim(chip, pval.intval); } /* Loading Loading @@ -1235,6 +1245,7 @@ static enum power_supply_property smb1390_charge_pump_props[] = { POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, POWER_SUPPLY_PROP_MIN_ICL, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_PARALLEL_MODE, }; static int smb1390_get_prop(struct power_supply *psy, Loading Loading @@ -1334,6 +1345,9 @@ static int smb1390_get_prop(struct power_supply *psy, val->strval = (chip->pmic_rev_id->rev4 > 2) ? "SMB1390_V3" : "SMB1390_V2"; break; case POWER_SUPPLY_PROP_PARALLEL_MODE: val->intval = chip->pl_input_mode; break; default: smb1390_dbg(chip, PR_MISC, "charge pump power supply get prop %d not supported\n", prop); Loading Loading @@ -1460,6 +1474,11 @@ static int smb1390_parse_dt(struct smb1390 *chip) of_property_read_u32(chip->dev->of_node, "qcom,parallel-output-mode", &chip->pl_output_mode); /* Default parallel input configuration is USBMID connection */ chip->pl_input_mode = POWER_SUPPLY_PL_USBMID_USBMID; of_property_read_u32(chip->dev->of_node, "qcom,parallel-input-mode", &chip->pl_input_mode); chip->cp_slave_thr_taper_ua = chip->min_ilim_ua * 3; of_property_read_u32(chip->dev->of_node, "qcom,cp-slave-thr-taper-ua", &chip->cp_slave_thr_taper_ua); Loading include/linux/pmic-voter.h +2 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ enum votable_type { bool is_client_vote_enabled(struct votable *votable, const char *client_str); bool is_client_vote_enabled_locked(struct votable *votable, const char *client_str); bool is_override_vote_enabled(struct votable *votable); bool is_override_vote_enabled_locked(struct votable *votable); int get_client_vote(struct votable *votable, const char *client_str); int get_client_vote_locked(struct votable *votable, const char *client_str); int get_effective_result(struct votable *votable); Loading Loading
drivers/power/supply/qcom/battery.c +63 −14 Original line number Diff line number Diff line Loading @@ -131,6 +131,11 @@ enum { RESTRICT_CHG_CURRENT, FCC_STEPPING_IN_PROGRESS, }; enum { PARALLEL_INPUT_MODE, PARALLEL_OUTPUT_MODE, }; /********* * HELPER* *********/ Loading @@ -143,23 +148,61 @@ static bool is_cp_available(struct pl_data *chip) return !!chip->cp_master_psy; } static bool cp_ilim_boost_enabled(struct pl_data *chip) static int cp_get_parallel_mode(struct pl_data *chip, int mode) { union power_supply_propval pval = {-1, }; union power_supply_propval pval = {-EINVAL, }; int rc = -EINVAL; if (is_cp_available(chip)) power_supply_get_property(chip->cp_master_psy, if (!is_cp_available(chip)) return -EINVAL; switch (mode) { case PARALLEL_INPUT_MODE: rc = power_supply_get_property(chip->cp_master_psy, POWER_SUPPLY_PROP_PARALLEL_MODE, &pval); break; case PARALLEL_OUTPUT_MODE: rc = power_supply_get_property(chip->cp_master_psy, POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, &pval); break; default: pr_err("Invalid mode request %d\n", mode); break; } if (rc < 0) pr_err("Failed to read CP topology for mode=%d rc=%d\n", mode, rc); return pval.intval == POWER_SUPPLY_PL_OUTPUT_VPH; return pval.intval; } /* * Adapter CC Mode: ILIM over-ridden explicitly, below takes no effect. * * Adapter CV mode: Configuration of ILIM for different topology is as below: * MID-VPH: * SMB1390 ILIM: independent of FCC and based on the AICL result or * PD advertised current, handled directly in SMB1390 * driver. * MID-VBAT: * SMB1390 ILIM: based on minimum of FCC portion of SMB1390 or ICL. * USBIN-VBAT: * SMB1390 ILIM: based on FCC portion of SMB1390 and independent of ICL. */ static void cp_configure_ilim(struct pl_data *chip, const char *voter, int ilim) { if (!is_cp_available(chip)) return; if (cp_get_parallel_mode(chip, PARALLEL_OUTPUT_MODE) == POWER_SUPPLY_PL_OUTPUT_VPH) return; if (!chip->cp_ilim_votable) chip->cp_ilim_votable = find_votable("CP_ILIM"); if (!cp_ilim_boost_enabled(chip) && chip->cp_ilim_votable) if (chip->cp_ilim_votable) vote(chip->cp_ilim_votable, voter, true, ilim); } Loading Loading @@ -726,12 +769,13 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data, chip->cp_disable_votable = find_votable("CP_DISABLE"); if (chip->cp_disable_votable) { if (cp_ilim_boost_enabled(chip)) { if (cp_get_parallel_mode(chip, PARALLEL_OUTPUT_MODE) == POWER_SUPPLY_PL_OUTPUT_VPH) { power_supply_get_property(chip->cp_master_psy, POWER_SUPPLY_PROP_MIN_ICL, &pval); /* * With ILIM boost feature ILIM configuration is * independent of battery FCC, disable CP if FCC/2 * With VPH output configuration ILIM is configured * independent of battery FCC, disable CP here if FCC/2 * falls below MIN_ICL supported by CP. */ if ((total_fcc_ua / 2) < pval.intval) Loading Loading @@ -926,8 +970,7 @@ static void fcc_stepper_work(struct work_struct *work) stepper_exit: chip->main_fcc_ua = main_fcc; chip->slave_fcc_ua = parallel_fcc; cp_configure_ilim(chip, FCC_VOTER, chip->main_fcc_ua / 2); cp_configure_ilim(chip, FCC_VOTER, chip->slave_fcc_ua / 2); if (reschedule_ms) { schedule_delayed_work(&chip->fcc_stepper_work, Loading Loading @@ -1044,6 +1087,9 @@ static int usb_icl_vote_callback(struct votable *votable, void *data, vote(chip->pl_disable_votable, ICL_CHANGE_VOTER, false, 0); /* Configure ILIM based on AICL result only if input mode is USBMID */ if (cp_get_parallel_mode(chip, PARALLEL_INPUT_MODE) == POWER_SUPPLY_PL_USBMID_USBMID) cp_configure_ilim(chip, ICL_CHANGE_VOTER, icl_ua); return 0; Loading Loading @@ -1087,7 +1133,7 @@ static int pl_disable_vote_callback(struct votable *votable, struct pl_data *chip = data; union power_supply_propval pval = {0, }; int master_fcc_ua = 0, total_fcc_ua = 0, slave_fcc_ua = 0; int rc = 0; int rc = 0, cp_ilim; bool disable = false; if (!is_main_available(chip)) Loading Loading @@ -1271,7 +1317,10 @@ static int pl_disable_vote_callback(struct votable *votable, /* main psy gets all share */ vote(chip->fcc_main_votable, MAIN_FCC_VOTER, true, total_fcc_ua); cp_configure_ilim(chip, FCC_VOTER, total_fcc_ua / 2); cp_ilim = total_fcc_ua - get_effective_result_locked( chip->fcc_main_votable); if (cp_ilim > 0) cp_configure_ilim(chip, FCC_VOTER, cp_ilim / 2); /* reset parallel FCC */ chip->slave_fcc_ua = 0; Loading
drivers/power/supply/qcom/pmic-voter.c +77 −3 Original line number Diff line number Diff line Loading @@ -166,7 +166,7 @@ static int get_client_id(struct votable *votable, const char *client_str) static char *get_client_str(struct votable *votable, int client_id) { if (client_id == -EINVAL) if (!votable || (client_id == -EINVAL)) return NULL; return votable->client_strs[client_id]; Loading @@ -182,6 +182,38 @@ void unlock_votable(struct votable *votable) mutex_unlock(&votable->vote_lock); } /** * is_override_vote_enabled() - * is_override_vote_enabled_locked() - * The unlocked and locked variants of getting whether override vote is enabled. * @votable: the votable object * * Returns: * True if the client's vote is enabled; false otherwise. */ bool is_override_vote_enabled_locked(struct votable *votable) { if (!votable) return false; return votable->override_result != -EINVAL; } bool is_override_vote_enabled(struct votable *votable) { bool enable; if (!votable) return false; lock_votable(votable); enable = is_override_vote_enabled_locked(votable); unlock_votable(votable); return enable; } /** * is_client_vote_enabled() - * is_client_vote_enabled_locked() - Loading @@ -196,8 +228,13 @@ void unlock_votable(struct votable *votable) bool is_client_vote_enabled_locked(struct votable *votable, const char *client_str) { int client_id = get_client_id(votable, client_str); int client_id; if (!votable || !client_str) return false; client_id = get_client_id(votable, client_str); if (client_id < 0) return false; Loading @@ -208,6 +245,9 @@ bool is_client_vote_enabled(struct votable *votable, const char *client_str) { bool enabled; if (!votable || !client_str) return false; lock_votable(votable); enabled = is_client_vote_enabled_locked(votable, client_str); unlock_votable(votable); Loading @@ -228,8 +268,12 @@ bool is_client_vote_enabled(struct votable *votable, const char *client_str) */ int get_client_vote_locked(struct votable *votable, const char *client_str) { int client_id = get_client_id(votable, client_str); int client_id; if (!votable || !client_str) return -EINVAL; client_id = get_client_id(votable, client_str); if (client_id < 0) return -EINVAL; Loading @@ -244,6 +288,9 @@ int get_client_vote(struct votable *votable, const char *client_str) { int value; if (!votable || !client_str) return -EINVAL; lock_votable(votable); value = get_client_vote_locked(votable, client_str); unlock_votable(votable); Loading @@ -269,6 +316,9 @@ int get_client_vote(struct votable *votable, const char *client_str) */ int get_effective_result_locked(struct votable *votable) { if (!votable) return -EINVAL; if (votable->force_active) return votable->force_val; Loading @@ -282,6 +332,9 @@ int get_effective_result(struct votable *votable) { int value; if (!votable) return -EINVAL; lock_votable(votable); value = get_effective_result_locked(votable); unlock_votable(votable); Loading @@ -308,6 +361,9 @@ int get_effective_result(struct votable *votable) */ const char *get_effective_client_locked(struct votable *votable) { if (!votable) return NULL; if (votable->force_active) return DEBUG_FORCE_CLIENT; Loading @@ -321,6 +377,9 @@ const char *get_effective_client(struct votable *votable) { const char *client_str; if (!votable) return NULL; lock_votable(votable); client_str = get_effective_client_locked(votable); unlock_votable(votable); Loading Loading @@ -358,6 +417,9 @@ int vote(struct votable *votable, const char *client_str, bool enabled, int val) int rc = 0; bool similar_vote = false; if (!votable || !client_str) return -EINVAL; lock_votable(votable); client_id = get_client_id(votable, client_str); Loading Loading @@ -463,6 +525,9 @@ int vote_override(struct votable *votable, const char *override_client, { int rc = 0; if (!votable || !override_client) return -EINVAL; lock_votable(votable); if (votable->force_active) { votable->override_result = enabled ? val : -EINVAL; Loading Loading @@ -493,6 +558,9 @@ int rerun_election(struct votable *votable) int rc = 0; int effective_result; if (!votable) return -EINVAL; lock_votable(votable); effective_result = get_effective_result_locked(votable); if (votable->callback) Loading @@ -510,6 +578,9 @@ struct votable *find_votable(const char *name) struct votable *v; bool found = false; if (!name) return NULL; spin_lock_irqsave(&votable_list_slock, flags); if (list_empty(&votable_list)) goto out; Loading Loading @@ -642,6 +713,9 @@ struct votable *create_votable(const char *name, struct votable *votable; unsigned long flags; if (!name) return ERR_PTR(-EINVAL); votable = find_votable(name); if (votable) return ERR_PTR(-EEXIST); Loading
drivers/power/supply/qcom/smb1390-charger-psy.c +41 −22 Original line number Diff line number Diff line Loading @@ -204,6 +204,7 @@ struct smb1390 { u32 max_temp_alarm_degc; u32 max_cutoff_soc; u32 pl_output_mode; u32 pl_input_mode; u32 cp_role; enum isns_mode current_capability; bool batt_soc_validated; Loading Loading @@ -994,6 +995,36 @@ static int smb1390_notifier_cb(struct notifier_block *nb, #define ILIM_NR 10 #define ILIM_DR 8 #define ILIM_FACTOR(ilim) ((ilim * ILIM_NR) / ILIM_DR) static void smb1390_configure_ilim(struct smb1390 *chip, int mode) { int rc; union power_supply_propval pval = {0, }; /* PPS adapter reply on the current advertised by the adapter */ if ((chip->pl_output_mode == POWER_SUPPLY_PL_OUTPUT_VPH) && (mode == POWER_SUPPLY_CP_PPS)) { rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_PD_CURRENT_MAX, &pval); if (rc < 0) pr_err("Couldn't get PD CURRENT MAX rc=%d\n", rc); else vote(chip->ilim_votable, ICL_VOTER, true, ILIM_FACTOR(pval.intval)); } /* QC3.0/Wireless adapter rely on the settled AICL for USBMID_USBMID */ if ((chip->pl_input_mode == POWER_SUPPLY_PL_USBMID_USBMID) && (mode == POWER_SUPPLY_CP_HVDCP3)) { rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval); if (rc < 0) pr_err("Couldn't get usb aicl rc=%d\n", rc); else vote(chip->ilim_votable, ICL_VOTER, true, pval.intval); } } static void smb1390_status_change_work(struct work_struct *work) { struct smb1390 *chip = container_of(work, struct smb1390, Loading Loading @@ -1047,28 +1078,7 @@ static void smb1390_status_change_work(struct work_struct *work) pval.intval); } else { vote(chip->ilim_votable, WIRELESS_VOTER, false, 0); if ((chip->pl_output_mode == POWER_SUPPLY_PL_OUTPUT_VPH) && (pval.intval == POWER_SUPPLY_CP_PPS)) { rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_PD_CURRENT_MAX, &pval); if (rc < 0) pr_err("Couldn't get PD CURRENT MAX rc=%d\n", rc); else vote(chip->ilim_votable, ICL_VOTER, true, ILIM_FACTOR(pval.intval)); } else { rc = power_supply_get_property(chip->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval); if (rc < 0) pr_err("Couldn't get usb aicl rc=%d\n", rc); else vote(chip->ilim_votable, ICL_VOTER, true, pval.intval); } smb1390_configure_ilim(chip, pval.intval); } /* Loading Loading @@ -1235,6 +1245,7 @@ static enum power_supply_property smb1390_charge_pump_props[] = { POWER_SUPPLY_PROP_PARALLEL_OUTPUT_MODE, POWER_SUPPLY_PROP_MIN_ICL, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_PARALLEL_MODE, }; static int smb1390_get_prop(struct power_supply *psy, Loading Loading @@ -1334,6 +1345,9 @@ static int smb1390_get_prop(struct power_supply *psy, val->strval = (chip->pmic_rev_id->rev4 > 2) ? "SMB1390_V3" : "SMB1390_V2"; break; case POWER_SUPPLY_PROP_PARALLEL_MODE: val->intval = chip->pl_input_mode; break; default: smb1390_dbg(chip, PR_MISC, "charge pump power supply get prop %d not supported\n", prop); Loading Loading @@ -1460,6 +1474,11 @@ static int smb1390_parse_dt(struct smb1390 *chip) of_property_read_u32(chip->dev->of_node, "qcom,parallel-output-mode", &chip->pl_output_mode); /* Default parallel input configuration is USBMID connection */ chip->pl_input_mode = POWER_SUPPLY_PL_USBMID_USBMID; of_property_read_u32(chip->dev->of_node, "qcom,parallel-input-mode", &chip->pl_input_mode); chip->cp_slave_thr_taper_ua = chip->min_ilim_ua * 3; of_property_read_u32(chip->dev->of_node, "qcom,cp-slave-thr-taper-ua", &chip->cp_slave_thr_taper_ua); Loading
include/linux/pmic-voter.h +2 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ enum votable_type { bool is_client_vote_enabled(struct votable *votable, const char *client_str); bool is_client_vote_enabled_locked(struct votable *votable, const char *client_str); bool is_override_vote_enabled(struct votable *votable); bool is_override_vote_enabled_locked(struct votable *votable); int get_client_vote(struct votable *votable, const char *client_str); int get_client_vote_locked(struct votable *votable, const char *client_str); int get_effective_result(struct votable *votable); Loading