Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84bd424f authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "pmic-voter: add support to report override votes"

parents 9f756aa8 0696f70e
Loading
Loading
Loading
Loading
+63 −14
Original line number Diff line number Diff line
@@ -131,6 +131,11 @@ enum {
	RESTRICT_CHG_CURRENT,
	FCC_STEPPING_IN_PROGRESS,
};

enum {
	PARALLEL_INPUT_MODE,
	PARALLEL_OUTPUT_MODE,
};
/*********
 * HELPER*
 *********/
@@ -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);
}

@@ -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)
@@ -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,
@@ -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;
@@ -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))
@@ -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;
+77 −3
Original line number Diff line number Diff line
@@ -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];
@@ -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() -
@@ -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;

@@ -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);
@@ -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;

@@ -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);
@@ -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;

@@ -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);
@@ -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;

@@ -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);
@@ -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);
@@ -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;
@@ -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)
@@ -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;
@@ -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);
+41 −22
Original line number Diff line number Diff line
@@ -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;
@@ -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,
@@ -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);
		}

		/*
@@ -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,
@@ -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);
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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);