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

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

Merge "power: smb1390-psy: Configure IREV and main's ICL to prevent IREV condition"

parents b2414e47 f590dae7
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -561,10 +561,17 @@ static int smb5_parse_dt(struct smb5 *chip)
	chg->hw_skin_temp_mitigation = of_property_read_bool(node,
					"qcom,hw-skin-temp-mitigation");

	chg->en_skin_therm_mitigation = of_property_read_bool(node,
					"qcom,en-skin-therm-mitigation");

	chg->connector_pull_up = -EINVAL;
	of_property_read_u32(node, "qcom,connector-internal-pull-kohm",
					&chg->connector_pull_up);

	chg->smb_pull_up = -EINVAL;
	of_property_read_u32(node, "qcom,smb-internal-pull-kohm",
					&chg->smb_pull_up);

	chip->dt.adc_based_aicl = of_property_read_bool(node,
					"qcom,adc-based-aicl");

@@ -682,6 +689,7 @@ static enum power_supply_property smb5_usb_props[] = {
	POWER_SUPPLY_PROP_QC_OPTI_DISABLE,
	POWER_SUPPLY_PROP_VOLTAGE_VPH,
	POWER_SUPPLY_PROP_THERM_ICL_LIMIT,
	POWER_SUPPLY_PROP_SKIN_HEALTH,
};

static int smb5_usb_get_prop(struct power_supply *psy,
@@ -856,6 +864,9 @@ static int smb5_usb_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_ADAPTER_CC_MODE:
		val->intval = chg->adapter_cc_mode;
		break;
	case POWER_SUPPLY_PROP_SKIN_HEALTH:
		val->intval = smblib_get_skin_temp_status(chg);
		break;
	default:
		pr_err("get prop %d is not supported in usb\n", psp);
		rc = -EINVAL;
@@ -1117,6 +1128,7 @@ static enum power_supply_property smb5_usb_main_props[] = {
	POWER_SUPPLY_PROP_FORCE_MAIN_FCC,
	POWER_SUPPLY_PROP_FORCE_MAIN_ICL,
	POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL,
	POWER_SUPPLY_PROP_HEALTH,
};

static int smb5_usb_main_get_prop(struct power_supply *psy,
@@ -1176,6 +1188,10 @@ static int smb5_usb_main_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL:
		val->intval = chg->comp_clamp_level;
		break;
	/* Use this property to report SMB health */
	case POWER_SUPPLY_PROP_HEALTH:
		val->intval = smblib_get_prop_smb_health(chg);
		break;
	default:
		pr_debug("get prop %d is not supported in usb-main\n", psp);
		rc = -EINVAL;
@@ -2830,6 +2846,17 @@ static int smb5_init_hw(struct smb5 *chip)
		}
	}

	if (chg->smb_pull_up != -EINVAL) {
		rc = smb5_configure_internal_pull(chg, SMB_THERM,
				get_valid_pullup(chg->smb_pull_up));
		if (rc < 0) {
			dev_err(chg->dev,
				"Couldn't configure SMB pull-up rc=%d\n",
				rc);
			return rc;
		}
	}

	return rc;
}

+82 −11
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@
#define CORE_FTRIM_CTRL_REG		0x1031
#define TEMP_ALERT_LVL_MASK		GENMASK(6, 5)
#define TEMP_ALERT_LVL_SHIFT		5
#define TEMP_BUFFER_OUTPUT_BIT		BIT(7)

#define CORE_FTRIM_LVL_REG		0x1033
#define CFG_WIN_HI_MASK			GENMASK(3, 2)
@@ -81,6 +82,7 @@

#define CORE_FTRIM_MISC_REG		0x1034
#define TR_WIN_1P5X_BIT			BIT(0)
#define TR_IREV_BIT			BIT(1)
#define WINDOW_DETECTION_DELTA_X1P0	0
#define WINDOW_DETECTION_DELTA_X1P5	1

@@ -104,6 +106,8 @@
#define SOC_LEVEL_VOTER		"SOC_LEVEL_VOTER"
#define HW_DISABLE_VOTER	"HW_DISABLE_VOTER"
#define CC_MODE_VOTER		"CC_MODE_VOTER"
#define MAIN_DISABLE_VOTER	"MAIN_DISABLE_VOTER"
#define TAPER_MAIN_ICL_LIMIT_VOTER	"TAPER_MAIN_ICL_LIMIT_VOTER"

#define CP_MASTER		0
#define CP_SLAVE		1
@@ -112,6 +116,7 @@
#define MAX_ILIM_DUAL_CP_UA		6400000
#define CC_MODE_TAPER_DELTA_UA		200000
#define DEFAULT_TAPER_DELTA_UA		100000
#define CC_MODE_TAPER_MAIN_ICL_UA	500000

#define smb1390_dbg(chip, reason, fmt, ...)				\
	do {								\
@@ -180,6 +185,8 @@ struct smb1390 {
	struct votable		*fcc_votable;
	struct votable		*fv_votable;
	struct votable		*cp_awake_votable;
	struct votable		*slave_disable_votable;
	struct votable		*usb_icl_votable;

	/* power supplies */
	struct power_supply	*cps_psy;
@@ -208,6 +215,7 @@ struct smb1390 {
	enum isns_mode		current_capability;
	bool			batt_soc_validated;
	int			cp_slave_thr_taper_ua;
	int			cc_mode_taper_main_icl_ua;
};

struct smb_cfg {
@@ -327,6 +335,14 @@ static bool is_psy_voter_available(struct smb1390 *chip)
		}
	}

	if (!chip->usb_icl_votable) {
		chip->usb_icl_votable = find_votable("USB_ICL");
		if (!chip->usb_icl_votable) {
			smb1390_dbg(chip, PR_EXT_DEPENDENCY, "Couldn't find ICL votable\n");
			return false;
		}
	}

	if (!chip->disable_votable) {
		smb1390_dbg(chip, PR_MISC, "Couldn't find CP DISABLE votable\n");
		return false;
@@ -839,15 +855,16 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data,
{
	struct smb1390 *chip = data;
	int rc = 0;
	u8 mask, val;

	if (!is_psy_voter_available(chip) || chip->suspended)
		return -EAGAIN;

	mask = CMD_EN_SWITCHER_BIT | CMD_EN_SL_BIT;
	val = is_cps_available(chip) ? mask : CMD_EN_SWITCHER_BIT;
	rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, mask,
				  disable ? 0 : val);
	if (is_cps_available(chip))
		vote(chip->slave_disable_votable, MAIN_DISABLE_VOTER,
					disable ? true : false, 0);

	rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, CMD_EN_SWITCHER_BIT,
				  disable ? 0 : CMD_EN_SWITCHER_BIT);
	if (rc < 0) {
		pr_err("Couldn't write CORE_CONTROL1_REG, rc=%d\n", rc);
		return rc;
@@ -861,6 +878,21 @@ static int smb1390_disable_vote_cb(struct votable *votable, void *data,
	return rc;
}

static int smb1390_slave_disable_vote_cb(struct votable *votable, void *data,
			      int disable, const char *client)
{
	struct smb1390 *chip = data;
	int rc;

	rc = smb1390_masked_write(chip, CORE_CONTROL1_REG, CMD_EN_SL_BIT,
					disable ? 0 : CMD_EN_SL_BIT);
	if (rc < 0)
		pr_err("Couldn't %s slave rc=%d\n",
				disable ? "disable" : "enable", rc);

	return rc;
}

static int smb1390_ilim_vote_cb(struct votable *votable, void *data,
			      int ilim_uA, const char *client)
{
@@ -1081,6 +1113,10 @@ static void smb1390_status_change_work(struct work_struct *work)
		vote(chip->fcc_votable, CP_VOTER, false, 0);
		vote(chip->disable_votable, SOC_LEVEL_VOTER, true, 0);
		vote_override(chip->ilim_votable, CC_MODE_VOTER, false, 0);
		vote(chip->slave_disable_votable, TAPER_END_VOTER, false, 0);
		vote(chip->slave_disable_votable, MAIN_DISABLE_VOTER, true, 0);
		vote_override(chip->usb_icl_votable, TAPER_MAIN_ICL_LIMIT_VOTER,
								false, 0);
	}

out:
@@ -1091,18 +1127,14 @@ static void smb1390_status_change_work(struct work_struct *work)
static int smb1390_validate_slave_chg_taper(struct smb1390 *chip, int fcc_uA)
{
	int rc = 0;
	u8 mask;

	/*
	 * In Collapse mode, while in Taper, Disable the slave SMB1390
	 * when FCC drops below a specified threshold.
	 */
	if (fcc_uA < (chip->cp_slave_thr_taper_ua) && is_cps_available(chip)) {
		mask = CMD_EN_SWITCHER_BIT | CMD_EN_SL_BIT;
		rc = smb1390_masked_write(chip, CORE_CONTROL1_REG,
						  mask, CMD_EN_SWITCHER_BIT);
		if (rc < 0)
			return rc;
		vote(chip->slave_disable_votable, TAPER_END_VOTER,
					true, 0);
		/*
		 * Set ILIM of master SMB1390 to Max value = 3.2A once slave is
		 * disabled to prevent ILIM irq storm.
@@ -1111,6 +1143,10 @@ static int smb1390_validate_slave_chg_taper(struct smb1390 *chip, int fcc_uA)
									fcc_uA);
		vote_override(chip->ilim_votable, CC_MODE_VOTER,
						true, MAX_ILIM_DUAL_CP_UA);
		if (chip->usb_icl_votable)
			vote_override(chip->usb_icl_votable,
				      TAPER_MAIN_ICL_LIMIT_VOTER,
				      true, chip->cc_mode_taper_main_icl_ua);
	}

	return rc;
@@ -1163,6 +1199,15 @@ static void smb1390_taper_work(struct work_struct *work)
			if (fcc_uA < (chip->min_ilim_ua * 2)) {
				vote(chip->disable_votable, TAPER_END_VOTER,
								true, 0);
				/*
				 * When master CP is disabled, reset all votes
				 * on ICL to enable Main charger to pump
				 * charging current.
				 */
				if (chip->usb_icl_votable)
					vote_override(chip->usb_icl_votable,
						TAPER_MAIN_ICL_LIMIT_VOTER,
						false, 0);
				goto out;
			}
		} else {
@@ -1415,6 +1460,12 @@ static int smb1390_parse_dt(struct smb1390 *chip)
	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);

	chip->cc_mode_taper_main_icl_ua = CC_MODE_TAPER_MAIN_ICL_UA;
	of_property_read_u32(chip->dev->of_node,
			     "qcom,cc-mode-taper-main-icl-ua",
			     &chip->cc_mode_taper_main_icl_ua);

	return 0;
}

@@ -1438,6 +1489,11 @@ static int smb1390_create_votables(struct smb1390 *chip)
	if (IS_ERR(chip->ilim_votable))
		return PTR_ERR(chip->ilim_votable);

	chip->slave_disable_votable = create_votable("CP_SLAVE_DISABLE",
			VOTE_SET_ANY, smb1390_slave_disable_vote_cb, chip);
	if (IS_ERR(chip->slave_disable_votable))
		return PTR_ERR(chip->slave_disable_votable);

	/*
	 * charge pump is initially disabled; this indirectly votes to allow
	 * traditional parallel charging if present
@@ -1507,6 +1563,12 @@ static int smb1390_init_hw(struct smb1390 *chip)
		return rc;
	}

	/* Configure IREV threshold to 200mA */
	rc = smb1390_masked_write(chip, CORE_FTRIM_MISC_REG, TR_IREV_BIT, 0);
	if (rc < 0) {
		pr_err("Couldn't configure IREV threshold rc=%d\n", rc);
		return rc;
	}
	/*
	 * If the slave charger has registered, configure Master SMB1390 for
	 * triple-chg config, else configure for dual. Later, if the slave
@@ -1829,6 +1891,15 @@ static int smb1390_slave_probe(struct smb1390 *chip)
	if (rc < 0)
		return rc;

	/* Configure Slave CP Temp buffer O/P to High Impedance */
	rc = smb1390_masked_write(chip, CORE_FTRIM_CTRL_REG,
				  TEMP_BUFFER_OUTPUT_BIT,
				  TEMP_BUFFER_OUTPUT_BIT);
	if (rc < 0) {
		pr_err("Couldn't configure Slave temp Buffer rc=%d\n", rc);
		return rc;
	}

	rc = smb1390_init_cps_psy(chip);
	if (rc < 0)
		pr_err("Couldn't initialize cps psy rc=%d\n", rc);
+52 −1
Original line number Diff line number Diff line
@@ -3675,6 +3675,54 @@ int smblib_get_pe_start(struct smb_charger *chg,
	return 0;
}

int smblib_get_prop_smb_health(struct smb_charger *chg)
{
	int rc;
	u8 stat;
	int input_present;

	rc = smblib_is_input_present(chg, &input_present);
	if (rc < 0)
		return rc;

	if (input_present == INPUT_NOT_PRESENT)
		return POWER_SUPPLY_HEALTH_UNKNOWN;

	if (chg->wa_flags & SW_THERM_REGULATION_WA) {
		if (chg->smb_temp == -ENODATA)
			return POWER_SUPPLY_HEALTH_UNKNOWN;

		if (chg->smb_temp > SMB_TEMP_RST_THRESH)
			return POWER_SUPPLY_HEALTH_OVERHEAT;

		if (chg->smb_temp > SMB_TEMP_REG_H_THRESH)
			return POWER_SUPPLY_HEALTH_HOT;

		if (chg->smb_temp > SMB_TEMP_REG_L_THRESH)
			return POWER_SUPPLY_HEALTH_WARM;

		return POWER_SUPPLY_HEALTH_COOL;
	}

	rc = smblib_read(chg, SMB_TEMP_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read SMB_TEMP_STATUS_REG, rc=%d\n",
				rc);
		return POWER_SUPPLY_HEALTH_UNKNOWN;
	}

	if (stat & SMB_TEMP_RST_BIT)
		return POWER_SUPPLY_HEALTH_OVERHEAT;

	if (stat & SMB_TEMP_UB_BIT)
		return POWER_SUPPLY_HEALTH_HOT;

	if (stat & SMB_TEMP_LB_BIT)
		return POWER_SUPPLY_HEALTH_WARM;

	return POWER_SUPPLY_HEALTH_COOL;
}

int smblib_get_prop_die_health(struct smb_charger *chg)
{
	int rc;
@@ -3763,11 +3811,14 @@ static int smblib_get_typec_connector_temp_status(struct smb_charger *chg)
	return POWER_SUPPLY_HEALTH_COOL;
}

static int smblib_get_skin_temp_status(struct smb_charger *chg)
int smblib_get_skin_temp_status(struct smb_charger *chg)
{
	int rc;
	u8 stat;

	if (!chg->en_skin_therm_mitigation)
		return POWER_SUPPLY_HEALTH_UNKNOWN;

	rc = smblib_read(chg, SKIN_TEMP_STATUS_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read SKIN_TEMP_STATUS_REG, rc=%d\n",
+4 −0
Original line number Diff line number Diff line
@@ -531,7 +531,9 @@ struct smb_charger {
	bool			hw_die_temp_mitigation;
	bool			hw_connector_mitigation;
	bool			hw_skin_temp_mitigation;
	bool			en_skin_therm_mitigation;
	int			connector_pull_up;
	int			smb_pull_up;
	int			aicl_5v_threshold_mv;
	int			default_aicl_5v_threshold_mv;
	int			aicl_cont_threshold_mv;
@@ -718,7 +720,9 @@ int smblib_get_pe_start(struct smb_charger *chg,
int smblib_get_prop_charger_temp(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_get_prop_die_health(struct smb_charger *chg);
int smblib_get_prop_smb_health(struct smb_charger *chg);
int smblib_get_prop_connector_health(struct smb_charger *chg);
int smblib_get_skin_temp_status(struct smb_charger *chg);
int smblib_get_prop_vph_voltage_now(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_set_prop_pd_current_max(struct smb_charger *chg,
+6 −0
Original line number Diff line number Diff line
@@ -493,6 +493,12 @@ enum {
#define CONNECTOR_TEMP_UB_BIT			BIT(1)
#define CONNECTOR_TEMP_LB_BIT			BIT(0)

#define SMB_TEMP_STATUS_REG			(MISC_BASE + 0x0A)
#define SMB_TEMP_SHDN_BIT			BIT(3)
#define SMB_TEMP_RST_BIT			BIT(2)
#define SMB_TEMP_UB_BIT				BIT(1)
#define SMB_TEMP_LB_BIT				BIT(0)

#define BARK_BITE_WDOG_PET_REG			(MISC_BASE + 0x43)
#define BARK_BITE_WDOG_PET_BIT			BIT(0)