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

Commit 13c4202d authored by Fenglin Wu's avatar Fenglin Wu Committed by Nicholas Troast
Browse files

smb-lib: fix slave BCL for HVDCP3



Currently, fixed 5V adapter voltage is used for calculating slave FCC.
When HVDCP 3.0 is used it skews the desired FCC distribution. Fix this
by using the HVDCP3 pulse count to determine the actual adapter voltage
when limiting the slave battery current.

Change-Id: Ib4735ffe7b6287a3e57e0f74eb24c13c6a2b7a5a
Signed-off-by: default avatarFenglin Wu <fenglinw@codeaurora.org>
Signed-off-by: default avatarNicholas Troast <ntroast@codeaurora.org>
parent d86ba09f
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
@@ -247,12 +247,11 @@ done:
 *  FCC  *
**********/
#define EFFICIENCY_PCT	80
#define MICRO_5V	5000000
static void split_fcc(struct pl_data *chip, int total_ua,
			int *master_ua, int *slave_ua)
{
	int rc, effective_total_ua, slave_limited_ua, hw_cc_delta_ua = 0,
		    aicl_settled_ua, input_limited_fcc_ua;
		icl_ua, adapter_uv, bcl_ua;
	union power_supply_propval pval = {0, };

	rc = power_supply_get_property(chip->main_psy,
@@ -262,24 +261,30 @@ static void split_fcc(struct pl_data *chip, int total_ua,
	else
		hw_cc_delta_ua = pval.intval;

	input_limited_fcc_ua = INT_MAX;
	bcl_ua = INT_MAX;
	if (chip->pl_mode == POWER_SUPPLY_PARALLEL_MID_MID) {
		rc = power_supply_get_property(chip->main_psy,
				       POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
				       &pval);
		if (rc < 0)
			aicl_settled_ua = 0;
		else
			aicl_settled_ua = pval.intval;
			       POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED, &pval);
		if (rc < 0) {
			pr_err("Couldn't get aicl settled value rc=%d\n", rc);
			return;
		}
		icl_ua = pval.intval;

		rc = power_supply_get_property(chip->main_psy,
			       POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED, &pval);
		if (rc < 0) {
			pr_err("Couldn't get adaptive voltage rc=%d\n", rc);
			return;
		}
		adapter_uv = pval.intval;

		input_limited_fcc_ua = div64_s64(
			(s64)aicl_settled_ua * MICRO_5V * EFFICIENCY_PCT,
			(s64)get_effective_result(chip->fv_votable)
			* 100);
		bcl_ua = div64_s64((s64)icl_ua * adapter_uv * EFFICIENCY_PCT,
			(s64)get_effective_result(chip->fv_votable) * 100);
	}

	effective_total_ua = max(0, total_ua + hw_cc_delta_ua);
	slave_limited_ua = min(effective_total_ua, input_limited_fcc_ua);
	slave_limited_ua = min(effective_total_ua, bcl_ua);
	*slave_ua = (slave_limited_ua * chip->slave_pct) / 100;
	*slave_ua = (*slave_ua * chip->taper_pct) / 100;
	*master_ua = max(0, total_ua - *slave_ua);
+4 −0
Original line number Diff line number Diff line
@@ -613,6 +613,7 @@ static enum power_supply_property smb2_usb_main_props[] = {
	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
	POWER_SUPPLY_PROP_TYPE,
	POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED,
	POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
	POWER_SUPPLY_PROP_FCC_DELTA,
	/*
	 * TODO move the TEMP and TEMP_MAX properties here,
@@ -645,6 +646,9 @@ static int smb2_usb_main_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_INPUT_CURRENT_SETTLED:
		rc = smblib_get_prop_input_current_settled(chg, val);
		break;
	case POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED:
		rc = smblib_get_prop_input_voltage_settled(chg, val);
		break;
	case POWER_SUPPLY_PROP_FCC_DELTA:
		rc = smblib_get_prop_fcc_delta(chg, val);
		break;
+34 −11
Original line number Diff line number Diff line
@@ -331,7 +331,6 @@ static const struct apsd_result *smblib_get_apsd_result(struct smb_charger *chg)
	return result;
}


/********************
 * REGISTER SETTERS *
 ********************/
@@ -1998,6 +1997,39 @@ int smblib_get_prop_input_current_settled(struct smb_charger *chg,
	return smblib_get_charge_param(chg, &chg->param.icl_stat, &val->intval);
}

#define HVDCP3_STEP_UV	200000
int smblib_get_prop_input_voltage_settled(struct smb_charger *chg,
						union power_supply_propval *val)
{
	const struct apsd_result *apsd_result = smblib_get_apsd_result(chg);
	int rc, pulses;
	u8 stat;

	val->intval = MICRO_5V;
	if (apsd_result == NULL) {
		smblib_err(chg, "APSD result is NULL\n");
		return 0;
	}

	switch (apsd_result->pst) {
	case POWER_SUPPLY_TYPE_USB_HVDCP_3:
		rc = smblib_read(chg, QC_PULSE_COUNT_STATUS_REG, &stat);
		if (rc < 0) {
			smblib_err(chg,
				"Couldn't read QC_PULSE_COUNT rc=%d\n", rc);
			return 0;
		}
		pulses = (stat & QC_PULSE_COUNT_MASK);
		val->intval = MICRO_5V + HVDCP3_STEP_UV * pulses;
		break;
	default:
		val->intval = MICRO_5V;
		break;
	}

	return 0;
}

int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg,
			       union power_supply_propval *val)
{
@@ -2887,6 +2919,7 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg)
	u8 stat;
	int pulses;

	power_supply_changed(chg->usb_main_psy);
	if (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB_HVDCP) {
		rc = smblib_read(chg, QC_CHANGE_STATUS_REG, &stat);
		if (rc < 0) {
@@ -2939,13 +2972,6 @@ static void smblib_hvdcp_adaptive_voltage_change(struct smb_charger *chg)
	}
}

static void smblib_handle_adaptive_voltage_done(struct smb_charger *chg,
						bool rising)
{
	smblib_dbg(chg, PR_INTERRUPT, "IRQ: adaptive-voltage-done %s\n",
		   rising ? "rising" : "falling");
}

/* triggers when HVDCP 3.0 authentication has finished */
static void smblib_handle_hvdcp_3p0_auth_done(struct smb_charger *chg,
					      bool rising)
@@ -3087,9 +3113,6 @@ irqreturn_t smblib_handle_usb_source_change(int irq, void *data)
	smblib_handle_hvdcp_3p0_auth_done(chg,
		(bool)(stat & QC_AUTH_DONE_STATUS_BIT));

	smblib_handle_adaptive_voltage_done(chg,
		(bool)(stat & VADP_CHANGE_DONE_AFTER_AUTH_BIT));

	smblib_handle_sdp_enumeration_done(chg,
		(bool)(stat & ENUMERATION_DONE_BIT));

+2 −0
Original line number Diff line number Diff line
@@ -377,6 +377,8 @@ int smblib_get_prop_pd_allowed(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_get_prop_input_current_settled(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_get_prop_input_voltage_settled(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_get_prop_pd_in_hard_reset(struct smb_charger *chg,
			       union power_supply_propval *val);
int smblib_get_pe_start(struct smb_charger *chg,