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

Commit 69d321dc authored by Abhijeet Dharmapurikar's avatar Abhijeet Dharmapurikar Committed by Ashay Jaiswal
Browse files

qcom: battery: remove ICL_REDUCTION support



Make battery library to directly update the split current
of the main charger via power_supply framework's set_property
API using CURRENT_MAX property. ICL_REDUCTION property
is no longer required.

Note that we are not doing initial ICL vote for USBIN USBIN,
instead when time comes to split aicl, we will read the input
current limit and if nothing is set, check what the hw determined
as the max limit and use that.

For a PD charger case where the apsd result will be unknown,
the current limit is expected to be set by the time aicl settled is
called. The 30 second delaying of parallel enabling, should give
PD engine ample time to set the current limits.

While at it clean up the way settled current change is tracked. Create
a variable that specifically indicates the total settled current seen
last time settled current was adjusted. This makes compare to an updated
settled current value easy.

CRs-Fixed: 2014572
Change-Id: I040b65e6380f2c12350ea44bf32e6981ff126f18
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
Signed-off-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
parent 17d9f038
Loading
Loading
Loading
Loading
+41 −17
Original line number Diff line number Diff line
@@ -56,8 +56,9 @@ struct pl_data {
	struct power_supply	*main_psy;
	struct power_supply	*pl_psy;
	struct power_supply	*batt_psy;
	struct power_supply	*usb_psy;
	int			charge_type;
	int			main_settled_ua;
	int			total_settled_ua;
	int			pl_settled_ua;
	struct class		qcom_batt_class;
	struct wakeup_source	*pl_ws;
@@ -93,15 +94,10 @@ enum {
********/
static void split_settled(struct pl_data *chip)
{
	int slave_icl_pct;
	int slave_icl_pct, total_current_ua;
	int slave_ua = 0, main_settled_ua = 0;
	union power_supply_propval pval = {0, };
	int rc;

	/* TODO some parallel chargers do not have a fine ICL resolution. For
	 * them implement a psy interface which returns the closest lower ICL
	 * for desired split
	 */
	int rc, total_settled_ua = 0;

	if ((chip->pl_mode != POWER_SUPPLY_PL_USBIN_USBIN)
		&& (chip->pl_mode != POWER_SUPPLY_PL_USBIN_USBIN_EXT))
@@ -123,12 +119,31 @@ static void split_settled(struct pl_data *chip)
		slave_icl_pct = max(0, chip->slave_pct - 10);
		slave_ua = ((main_settled_ua + chip->pl_settled_ua)
						* slave_icl_pct) / 100;
		total_settled_ua = main_settled_ua + chip->pl_settled_ua;
	}

	/* ICL_REDUCTION on main could be 0mA when pl is disabled */
	pval.intval = slave_ua;
	total_current_ua = get_effective_result_locked(chip->usb_icl_votable);
	if (total_current_ua < 0) {
		if (!chip->usb_psy)
			chip->usb_psy = power_supply_get_by_name("usb");
		if (!chip->usb_psy) {
			pr_err("Couldn't get usbpsy while splitting settled\n");
			return;
		}
		/* no client is voting, so get the total current from charger */
		rc = power_supply_get_property(chip->usb_psy,
			POWER_SUPPLY_PROP_HW_CURRENT_MAX, &pval);
		if (rc < 0) {
			pr_err("Couldn't get max current rc=%d\n", rc);
			return;
		}
		total_current_ua = pval.intval;
	}

	pval.intval = total_current_ua - slave_ua;
	/* Set ICL on main charger */
	rc = power_supply_set_property(chip->main_psy,
			POWER_SUPPLY_PROP_ICL_REDUCTION, &pval);
				POWER_SUPPLY_PROP_CURRENT_MAX, &pval);
	if (rc < 0) {
		pr_err("Couldn't change slave suspend state rc=%d\n", rc);
		return;
@@ -143,10 +158,12 @@ static void split_settled(struct pl_data *chip)
		return;
	}

	/* main_settled_ua represents the total capability of adapter */
	if (!chip->main_settled_ua)
		chip->main_settled_ua = main_settled_ua;
	chip->total_settled_ua = total_settled_ua;
	chip->pl_settled_ua = slave_ua;

	pl_dbg(chip, PR_PARALLEL,
		"Split total_current_ua=%d main_settled_ua=%d slave_ua=%d\n",
		total_current_ua, main_settled_ua, slave_ua);
}

static ssize_t version_show(struct class *c, struct class_attribute *attr,
@@ -528,7 +545,7 @@ static int pl_disable_vote_callback(struct votable *votable,
	int rc;

	chip->taper_pct = 100;
	chip->main_settled_ua = 0;
	chip->total_settled_ua = 0;
	chip->pl_settled_ua = 0;

	if (!pl_disable) { /* enable */
@@ -733,6 +750,7 @@ static void handle_main_charge_type(struct pl_data *chip)
static void handle_settled_icl_change(struct pl_data *chip)
{
	union power_supply_propval pval = {0, };
	int new_total_settled_ua;
	int rc;

	if (get_effective_result(chip->pl_disable_votable))
@@ -752,9 +770,15 @@ static void handle_settled_icl_change(struct pl_data *chip)
			return;
		}

		new_total_settled_ua = pval.intval + chip->pl_settled_ua;
		pl_dbg(chip, PR_PARALLEL,
			"total_settled_ua=%d settled_ua=%d new_total_settled_ua=%d\n",
			chip->total_settled_ua, pval.intval,
			new_total_settled_ua);

		/* If ICL change is small skip splitting */
		if (abs((chip->main_settled_ua - chip->pl_settled_ua)
				- pval.intval) > MIN_ICL_CHANGE_DELTA_UA)
		if (abs(new_total_settled_ua - chip->total_settled_ua)
						> MIN_ICL_CHANGE_DELTA_UA)
			split_settled(chip);
	} else {
		rerun_election(chip->fcc_votable);
+4 −7
Original line number Diff line number Diff line
@@ -414,6 +414,7 @@ static enum power_supply_property smb2_usb_props[] = {
	POWER_SUPPLY_PROP_BOOST_CURRENT,
	POWER_SUPPLY_PROP_PE_START,
	POWER_SUPPLY_PROP_CTM_CURRENT_MAX,
	POWER_SUPPLY_PROP_HW_CURRENT_MAX,
};

static int smb2_usb_get_prop(struct power_supply *psy,
@@ -502,6 +503,9 @@ static int smb2_usb_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CTM_CURRENT_MAX:
		val->intval = get_client_vote(chg->usb_icl_votable, CTM_VOTER);
		break;
	case POWER_SUPPLY_PROP_HW_CURRENT_MAX:
		rc = smblib_get_charge_current(chg, &val->intval);
		break;
	default:
		pr_err("get prop %d is not supported in usb\n", psp);
		rc = -EINVAL;
@@ -610,7 +614,6 @@ static int smb2_init_usb_psy(struct smb2 *chip)

static enum power_supply_property smb2_usb_main_props[] = {
	POWER_SUPPLY_PROP_VOLTAGE_MAX,
	POWER_SUPPLY_PROP_ICL_REDUCTION,
	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
	POWER_SUPPLY_PROP_TYPE,
	POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
@@ -635,9 +638,6 @@ static int smb2_usb_main_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
		rc = smblib_get_charge_param(chg, &chg->param.fv, &val->intval);
		break;
	case POWER_SUPPLY_PROP_ICL_REDUCTION:
		val->intval = chg->icl_reduction_ua;
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
		rc = smblib_get_charge_param(chg, &chg->param.fcc,
							&val->intval);
@@ -681,9 +681,6 @@ static int smb2_usb_main_set_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
		rc = smblib_set_charge_param(chg, &chg->param.fv, val->intval);
		break;
	case POWER_SUPPLY_PROP_ICL_REDUCTION:
		rc = smblib_set_icl_reduction(chg, val->intval);
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
		rc = smblib_set_charge_param(chg, &chg->param.fcc, val->intval);
		break;
+12 −54
Original line number Diff line number Diff line
@@ -696,13 +696,6 @@ static void smblib_uusb_removal(struct smb_charger *chg)
	if (rc < 0)
		smblib_err(chg,
			"Couldn't un-vote DCP from USB ICL rc=%d\n", rc);

	/* clear USB ICL vote for PL_USBIN_USBIN_VOTER */
	rc = vote(chg->usb_icl_votable, PL_USBIN_USBIN_VOTER, false, 0);
	if (rc < 0)
		smblib_err(chg,
			"Couldn't un-vote PL_USBIN_USBIN from USB ICL rc=%d\n",
			rc);
}

void smblib_suspend_on_debug_battery(struct smb_charger *chg)
@@ -871,8 +864,7 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua)
			goto enable_icl_changed_interrupt;
		}
	} else {
		rc = smblib_set_charge_param(chg, &chg->param.usb_icl,
				icl_ua - chg->icl_reduction_ua);
		rc = smblib_set_charge_param(chg, &chg->param.usb_icl, icl_ua);
		if (rc < 0) {
			smblib_err(chg, "Couldn't set HC ICL rc=%d\n", rc);
			goto enable_icl_changed_interrupt;
@@ -890,7 +882,7 @@ override_suspend_config:
			/* For std cable with type = SDP never override */
			override = false;
		else if (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB_CDP
			&& icl_ua - chg->icl_reduction_ua == 1500000)
			&& icl_ua == 1500000)
			/*
			 * For std cable with type = CDP override only if
			 * current is not 1500mA
@@ -2605,13 +2597,6 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
				"Couldn't un-vote DCP from USB ICL rc=%d\n",
				rc);

		/* clear USB ICL vote for PL_USBIN_USBIN_VOTER */
		rc = vote(chg->usb_icl_votable, PL_USBIN_USBIN_VOTER, false, 0);
		if (rc < 0)
			smblib_err(chg,
					"Couldn't un-vote PL_USBIN_USBIN from USB ICL rc=%d\n",
					rc);

		/* remove USB_PSY_VOTER */
		rc = vote(chg->usb_icl_votable, USB_PSY_VOTER, false, 0);
		if (rc < 0) {
@@ -2866,15 +2851,21 @@ int smblib_get_prop_fcc_delta(struct smb_charger *chg,
#define TYPEC_DEFAULT_CURRENT_MA	900000
#define TYPEC_MEDIUM_CURRENT_MA		1500000
#define TYPEC_HIGH_CURRENT_MA		3000000
static int smblib_get_charge_current(struct smb_charger *chg,
int smblib_get_charge_current(struct smb_charger *chg,
				int *total_current_ua)
{
	const struct apsd_result *apsd_result = smblib_update_usb_type(chg);
	union power_supply_propval val = {0, };
	int rc, typec_source_rd, current_ua;
	int rc = 0, typec_source_rd, current_ua;
	bool non_compliant;
	u8 stat5;

	if (chg->pd_active) {
		*total_current_ua =
			get_client_vote_locked(chg->usb_icl_votable, PD_VOTER);
		return rc;
	}

	rc = smblib_read(chg, TYPE_C_STATUS_5_REG, &stat5);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read TYPE_C_STATUS_5 rc=%d\n", rc);
@@ -2949,33 +2940,6 @@ static int smblib_get_charge_current(struct smb_charger *chg,
	return 0;
}

int smblib_set_icl_reduction(struct smb_charger *chg, int reduction_ua)
{
	int current_ua, rc;

	if (reduction_ua == 0) {
		vote(chg->usb_icl_votable, PL_USBIN_USBIN_VOTER, false, 0);
	} else {
		/*
		 * No usb_icl voter means we are defaulting to hw chosen
		 * max limit. We need a vote from s/w to enforce the reduction.
		 */
		if (get_effective_result(chg->usb_icl_votable) == -EINVAL) {
			rc = smblib_get_charge_current(chg, &current_ua);
			if (rc < 0) {
				pr_err("Failed to get ICL rc=%d\n", rc);
				return rc;
			}
			vote(chg->usb_icl_votable, PL_USBIN_USBIN_VOTER, true,
					current_ua);
		}
	}

	chg->icl_reduction_ua = reduction_ua;

	return rerun_election(chg->usb_icl_votable);
}

/************************
 * PARALLEL PSY GETTERS *
 ************************/
@@ -3584,12 +3548,6 @@ static void typec_source_removal(struct smb_charger *chg)
		smblib_err(chg,
			"Couldn't un-vote DCP from USB ICL rc=%d\n", rc);

	/* clear USB ICL vote for PL_USBIN_USBIN_VOTER */
	rc = vote(chg->usb_icl_votable, PL_USBIN_USBIN_VOTER, false, 0);
	if (rc < 0)
		smblib_err(chg,
			"Couldn't un-vote PL_USBIN_USBIN from USB ICL rc=%d\n",
			rc);
}

static void typec_source_insertion(struct smb_charger *chg)
+1 −3
Original line number Diff line number Diff line
@@ -322,8 +322,6 @@ struct smb_charger {
	/* extcon for VBUS / ID notification to USB for uUSB */
	struct extcon_dev	*extcon;

	int			icl_reduction_ua;

	/* qnovo */
	int			qnovo_fcc_ua;
	int			qnovo_fv_uv;
@@ -489,10 +487,10 @@ int smblib_rerun_apsd_if_required(struct smb_charger *chg);
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_set_icl_current(struct smb_charger *chg, int icl_ua);
int smblib_get_charge_current(struct smb_charger *chg, int *total_current_ua);

int smblib_init(struct smb_charger *chg);
int smblib_deinit(struct smb_charger *chg);