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

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

Merge "power: smb1390-psy: Support PPS constant current(CC) mode"

parents 29b89490 368b28ac
Loading
Loading
Loading
Loading
+56 −71
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@
#define ICL_LIMIT_VOTER			"ICL_LIMIT_VOTER"
#define FCC_STEPPER_VOTER		"FCC_STEPPER_VOTER"
#define FCC_VOTER			"FCC_VOTER"
#define MAIN_FCC_VOTER			"MAIN_FCC_VOTER"

struct pl_data {
	int			pl_mode;
@@ -67,6 +68,7 @@ struct pl_data {
	struct votable		*pl_enable_votable_indirect;
	struct votable		*cp_ilim_votable;
	struct votable		*cp_disable_votable;
	struct votable		*fcc_main_votable;
	struct delayed_work	status_change_work;
	struct work_struct	pl_disable_forever_work;
	struct work_struct	pl_taper_work;
@@ -560,17 +562,9 @@ static void get_fcc_stepper_params(struct pl_data *chip, int main_fcc_ua,
			int parallel_fcc_ua)
{
	union power_supply_propval pval = {0, };
	int rc;

	/* Read current FCC of main charger */
	rc = power_supply_get_property(chip->main_psy,
		POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval);
	if (rc < 0) {
		pr_err("Couldn't get main charger current fcc, rc=%d\n", rc);
		return;
	}
	chip->main_fcc_ua = pval.intval;

	chip->main_fcc_ua = get_effective_result(chip->fcc_main_votable);
	chip->main_step_fcc_dir = (main_fcc_ua > pval.intval) ?
				STEP_UP : STEP_DOWN;
	chip->main_step_fcc_count = abs((main_fcc_ua - pval.intval) /
@@ -690,6 +684,31 @@ static void pl_taper_work(struct work_struct *work)
	vote(chip->pl_awake_votable, TAPER_END_VOTER, false, 0);
}

static bool is_main_available(struct pl_data *chip)
{
	if (chip->main_psy)
		return true;

	chip->main_psy = power_supply_get_by_name("main");

	return !!chip->main_psy;
}

static int pl_fcc_main_vote_callback(struct votable *votable, void *data,
			int fcc_main_ua, const char *client)
{
	struct pl_data *chip = data;
	union power_supply_propval pval = {0,};

	if (!is_main_available(chip))
		return 0;

	pval.intval = fcc_main_ua;
	return  power_supply_set_property(chip->main_psy,
			  POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
			  &pval);
}

static int pl_fcc_vote_callback(struct votable *votable, void *data,
			int total_fcc_ua, const char *client)
{
@@ -738,6 +757,13 @@ static int pl_fcc_vote_callback(struct votable *votable, void *data,
	}

	rerun_election(chip->pl_disable_votable);
	/* When FCC changes, trigger psy changed event for CC mode */
	if (!chip->cp_master_psy)
		chip->cp_master_psy =
			power_supply_get_by_name("charge_pump_master");

	if (chip->cp_master_psy)
		power_supply_changed(chip->cp_master_psy);

	return 0;
}
@@ -794,14 +820,7 @@ static void fcc_stepper_work(struct work_struct *work)
		}

		main_fcc = get_effective_result_locked(chip->fcc_votable);
		pval.intval = main_fcc;
		rc = power_supply_set_property(chip->main_psy,
			POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval);
		if (rc < 0) {
			pr_err("Couldn't set main charger fcc, rc=%d\n", rc);
			goto out;
		}

		vote(chip->fcc_main_votable, FCC_STEPPER_VOTER, true, main_fcc);
		goto stepper_exit;
	}

@@ -862,22 +881,10 @@ static void fcc_stepper_work(struct work_struct *work)
		}

		/* Set main FCC */
		pval.intval = main_fcc;
		rc = power_supply_set_property(chip->main_psy,
			POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval);
		if (rc < 0) {
			pr_err("Couldn't set main charger fcc, rc=%d\n", rc);
			goto out;
		}
		vote(chip->fcc_main_votable, FCC_STEPPER_VOTER, true, main_fcc);
	} else {
		/* Set main FCC */
		pval.intval = main_fcc;
		rc = power_supply_set_property(chip->main_psy,
			POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, &pval);
		if (rc < 0) {
			pr_err("Couldn't set main charger fcc, rc=%d\n", rc);
			goto out;
		}
		vote(chip->fcc_main_votable, FCC_STEPPER_VOTER, true, main_fcc);

		/* Set parallel FCC */
		if (chip->pl_psy) {
@@ -1063,16 +1070,6 @@ static void pl_awake_work(struct work_struct *work)
	vote(chip->pl_awake_votable, PL_VOTER, false, 0);
}

static bool is_main_available(struct pl_data *chip)
{
	if (chip->main_psy)
		return true;

	chip->main_psy = power_supply_get_by_name("main");

	return !!chip->main_psy;
}

static bool is_batt_available(struct pl_data *chip)
{
	if (!chip->batt_psy)
@@ -1184,16 +1181,8 @@ static int pl_disable_vote_callback(struct votable *votable,
			 *	Set slave ICL then main FCC.
			 */
			if (slave_fcc_ua > chip->slave_fcc_ua) {
				pval.intval = master_fcc_ua;
				rc = power_supply_set_property(chip->main_psy,
				POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
					&pval);
				if (rc < 0) {
					pr_err("Could not set main fcc, rc=%d\n",
						rc);
					return rc;
				}

				vote(chip->fcc_main_votable, MAIN_FCC_VOTER,
							true, master_fcc_ua);
				pval.intval = slave_fcc_ua;
				rc = power_supply_set_property(chip->pl_psy,
				POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
@@ -1217,16 +1206,8 @@ static int pl_disable_vote_callback(struct votable *votable,
				}

				chip->slave_fcc_ua = slave_fcc_ua;

				pval.intval = master_fcc_ua;
				rc = power_supply_set_property(chip->main_psy,
				POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
					&pval);
				if (rc < 0) {
					pr_err("Could not set main fcc, rc=%d\n",
						rc);
					return rc;
				}
				vote(chip->fcc_main_votable, MAIN_FCC_VOTER,
							true, master_fcc_ua);
			}

			/*
@@ -1288,15 +1269,8 @@ static int pl_disable_vote_callback(struct votable *votable,
			}

			/* main psy gets all share */
			pval.intval = total_fcc_ua;
			rc = power_supply_set_property(chip->main_psy,
				POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
				&pval);
			if (rc < 0) {
				pr_err("Could not set main fcc, rc=%d\n", rc);
				return rc;
			}

			vote(chip->fcc_main_votable, MAIN_FCC_VOTER, true,
								total_fcc_ua);
			cp_configure_ilim(chip, FCC_VOTER, total_fcc_ua / 2);

			/* reset parallel FCC */
@@ -1711,13 +1685,22 @@ int qcom_batt_init(int smb_version)
	if (!chip->pl_ws)
		goto cleanup;

	chip->fcc_main_votable = create_votable("FCC_MAIN", VOTE_MIN,
					pl_fcc_main_vote_callback,
					chip);
	if (IS_ERR(chip->fcc_main_votable)) {
		rc = PTR_ERR(chip->fcc_main_votable);
		chip->fcc_main_votable = NULL;
		goto release_wakeup_source;
	}

	chip->fcc_votable = create_votable("FCC", VOTE_MIN,
					pl_fcc_vote_callback,
					chip);
	if (IS_ERR(chip->fcc_votable)) {
		rc = PTR_ERR(chip->fcc_votable);
		chip->fcc_votable = NULL;
		goto release_wakeup_source;
		goto destroy_votable;
	}

	chip->fv_votable = create_votable("FV", VOTE_MIN,
@@ -1813,6 +1796,7 @@ int qcom_batt_init(int smb_version)
	destroy_votable(chip->pl_disable_votable);
	destroy_votable(chip->fv_votable);
	destroy_votable(chip->fcc_votable);
	destroy_votable(chip->fcc_main_votable);
	destroy_votable(chip->usb_icl_votable);
release_wakeup_source:
	wakeup_source_unregister(chip->pl_ws);
@@ -1840,6 +1824,7 @@ void qcom_batt_deinit(void)
	destroy_votable(chip->pl_disable_votable);
	destroy_votable(chip->fv_votable);
	destroy_votable(chip->fcc_votable);
	destroy_votable(chip->fcc_main_votable);
	wakeup_source_unregister(chip->pl_ws);
	the_chip = NULL;
	kfree(chip);
+72 −0
Original line number Diff line number Diff line
@@ -255,6 +255,11 @@ enum {
	SMB_THERM,
};

static const struct clamp_config clamp_levels[] = {
	{ {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2E, 0x90} },
	{ {0x11C6, 0x11F9, 0x13F1}, {0x60, 0x2B, 0x9C} },
};

#define PMI632_MAX_ICL_UA	3000000
#define PM6150_MAX_FCC_UA	3000000
static int smb5_chg_config_init(struct smb5 *chip)
@@ -612,6 +617,33 @@ static int smb5_parse_dt(struct smb5 *chip)
	return 0;
}

static int smb5_set_prop_comp_clamp_level(struct smb_charger *chg,
			     const union power_supply_propval *val)
{
	int rc = 0, i;
	struct clamp_config clamp_config;
	enum comp_clamp_levels level;

	level = val->intval;
	if (level >= MAX_CLAMP_LEVEL) {
		pr_err("Invalid comp clamp level=%d\n", val->intval);
		return -EINVAL;
	}

	for (i = 0; i < ARRAY_SIZE(clamp_config.reg); i++) {
		rc = smblib_write(chg, clamp_levels[level].reg[i],
			     clamp_levels[level].val[i]);
		if (rc < 0)
			dev_err(chg->dev,
				"Failed to configure comp clamp settings for reg=0x%04x rc=%d\n",
				   clamp_levels[level].reg[i], rc);
	}

	chg->comp_clamp_level = val->intval;

	return rc;
}

/************************
 * USB PSY REGISTRATION *
 ************************/
@@ -643,6 +675,7 @@ static enum power_supply_property smb5_usb_props[] = {
	POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT,
	POWER_SUPPLY_PROP_SMB_EN_MODE,
	POWER_SUPPLY_PROP_SMB_EN_REASON,
	POWER_SUPPLY_PROP_ADAPTER_CC_MODE,
	POWER_SUPPLY_PROP_SCOPE,
	POWER_SUPPLY_PROP_MOISTURE_DETECTED,
	POWER_SUPPLY_PROP_HVDCP_OPTI_ALLOWED,
@@ -820,6 +853,9 @@ static int smb5_usb_get_prop(struct power_supply *psy,
		val->intval = get_client_vote(chg->usb_icl_votable,
					THERMAL_THROTTLE_VOTER);
		break;
	case POWER_SUPPLY_PROP_ADAPTER_CC_MODE:
		val->intval = chg->adapter_cc_mode;
		break;
	default:
		pr_err("get prop %d is not supported in usb\n", psp);
		rc = -EINVAL;
@@ -906,6 +942,9 @@ static int smb5_usb_set_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT:
		smblib_set_prop_usb_voltage_max_limit(chg, val);
		break;
	case POWER_SUPPLY_PROP_ADAPTER_CC_MODE:
		chg->adapter_cc_mode = val->intval;
		break;
	default:
		pr_err("set prop %d is not supported\n", psp);
		rc = -EINVAL;
@@ -923,6 +962,7 @@ static int smb5_usb_prop_is_writeable(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CONNECTOR_HEALTH:
	case POWER_SUPPLY_PROP_THERM_ICL_LIMIT:
	case POWER_SUPPLY_PROP_VOLTAGE_MAX_LIMIT:
	case POWER_SUPPLY_PROP_ADAPTER_CC_MODE:
		return 1;
	default:
		break;
@@ -1074,6 +1114,9 @@ static enum power_supply_property smb5_usb_main_props[] = {
	POWER_SUPPLY_PROP_TOGGLE_STAT,
	POWER_SUPPLY_PROP_MAIN_FCC_MAX,
	POWER_SUPPLY_PROP_IRQ_STATUS,
	POWER_SUPPLY_PROP_FORCE_MAIN_FCC,
	POWER_SUPPLY_PROP_FORCE_MAIN_ICL,
	POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL,
};

static int smb5_usb_main_get_prop(struct power_supply *psy,
@@ -1122,6 +1165,17 @@ static int smb5_usb_main_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_IRQ_STATUS:
		rc = smblib_get_irq_status(chg, val);
		break;
	case POWER_SUPPLY_PROP_FORCE_MAIN_FCC:
		rc = smblib_get_charge_param(chg, &chg->param.fcc,
							&val->intval);
		break;
	case POWER_SUPPLY_PROP_FORCE_MAIN_ICL:
		rc = smblib_get_charge_param(chg, &chg->param.usb_icl,
							&val->intval);
		break;
	case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL:
		val->intval = chg->comp_clamp_level;
		break;
	default:
		pr_debug("get prop %d is not supported in usb-main\n", psp);
		rc = -EINVAL;
@@ -1192,6 +1246,17 @@ static int smb5_usb_main_set_prop(struct power_supply *psy,
		chg->main_fcc_max = val->intval;
		rerun_election(chg->fcc_votable);
		break;
	case POWER_SUPPLY_PROP_FORCE_MAIN_FCC:
		vote_override(chg->fcc_main_votable, CC_MODE_VOTER,
				(val->intval < 0) ? false : true, val->intval);
		break;
	case POWER_SUPPLY_PROP_FORCE_MAIN_ICL:
		vote_override(chg->usb_icl_votable, CC_MODE_VOTER,
				(val->intval < 0) ? false : true, val->intval);
		break;
	case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL:
		rc = smb5_set_prop_comp_clamp_level(chg, val);
		break;
	default:
		pr_err("set prop %d is not supported\n", psp);
		rc = -EINVAL;
@@ -1209,6 +1274,9 @@ static int smb5_usb_main_prop_is_writeable(struct power_supply *psy,
	switch (psp) {
	case POWER_SUPPLY_PROP_TOGGLE_STAT:
	case POWER_SUPPLY_PROP_MAIN_FCC_MAX:
	case POWER_SUPPLY_PROP_FORCE_MAIN_FCC:
	case POWER_SUPPLY_PROP_FORCE_MAIN_ICL:
	case POWER_SUPPLY_PROP_COMP_CLAMP_LEVEL:
		rc = 1;
		break;
	default:
@@ -1399,6 +1467,7 @@ static enum power_supply_property smb5_batt_props[] = {
	POWER_SUPPLY_PROP_CURRENT_NOW,
	POWER_SUPPLY_PROP_CURRENT_QNOVO,
	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
	POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
	POWER_SUPPLY_PROP_TEMP,
	POWER_SUPPLY_PROP_TECHNOLOGY,
@@ -1493,6 +1562,9 @@ static int smb5_batt_get_prop(struct power_supply *psy,
		val->intval = get_client_vote(chg->fcc_votable,
					      BATT_PROFILE_VOTER);
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
		val->intval = get_effective_result(chg->fcc_votable);
		break;
	case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
		rc = smblib_get_prop_batt_iterm(chg, val);
		break;
+117 −9
Original line number Diff line number Diff line
@@ -103,11 +103,15 @@
#define SWITCHER_TOGGLE_VOTER	"SWITCHER_TOGGLE_VOTER"
#define SOC_LEVEL_VOTER		"SOC_LEVEL_VOTER"
#define HW_DISABLE_VOTER	"HW_DISABLE_VOTER"
#define CC_MODE_VOTER		"CC_MODE_VOTER"

#define CP_MASTER		0
#define CP_SLAVE		1
#define THERMAL_SUSPEND_DECIDEGC	1400
#define MAX_ILIM_UA			3200000
#define MAX_ILIM_DUAL_CP_UA		6400000
#define CC_MODE_TAPER_DELTA_UA		200000
#define DEFAULT_TAPER_DELTA_UA		100000

#define smb1390_dbg(chip, reason, fmt, ...)				\
	do {								\
@@ -202,6 +206,8 @@ struct smb1390 {
	u32			pl_output_mode;
	u32			cp_role;
	enum isns_mode		current_capability;
	bool			batt_soc_validated;
	int			cp_slave_thr_taper_ua;
};

struct smb_cfg {
@@ -356,6 +362,28 @@ static int smb1390_isns_mode_control(struct smb1390 *chip, enum isns_mode mode)
	return rc;
}

static bool smb1390_is_adapter_cc_mode(struct smb1390 *chip)
{
	int rc;
	union power_supply_propval pval = {0, };

	if (!chip->usb_psy) {
		chip->usb_psy = power_supply_get_by_name("usb");
		if (!chip->usb_psy)
			return false;
	}

	rc = power_supply_get_property(chip->usb_psy,
				POWER_SUPPLY_PROP_ADAPTER_CC_MODE,
				&pval);
	if (rc < 0) {
		pr_err("Couldn't get PPS CC mode status rc=%d\n", rc);
		return false;
	}

	return pval.intval;
}

static bool is_cps_available(struct smb1390 *chip)
{
	if (!chip->cps_psy)
@@ -697,6 +725,30 @@ static int smb1390_get_isns_slave(struct smb1390 *chip,
	return rc;
}

static int smb1390_get_cp_ilim(struct smb1390 *chip,
			       union power_supply_propval *val)
{
	int rc = 0, status;

	if (is_cps_available(chip)) {
		if (!chip->ilim_votable) {
			chip->ilim_votable = find_votable("CP_ILIM");
			if (!chip->ilim_votable)
				return -EINVAL;
		}

		val->intval = get_effective_result(chip->ilim_votable);
	} else {
		rc = smb1390_read(chip, CORE_FTRIM_ILIM_REG, &status);
		if (!rc)
			val->intval =
				((status & CFG_ILIM_MASK) * 100000)
					+ 500000;
	}

	return rc;
}

static int smb1390_is_batt_soc_valid(struct smb1390 *chip)
{
	int rc;
@@ -825,7 +877,8 @@ static int smb1390_ilim_vote_cb(struct votable *votable, void *data,
		return -EINVAL;
	}

	ilim_uA = min(ilim_uA, MAX_ILIM_UA);
	ilim_uA = min(ilim_uA, (is_cps_available(chip) ?
				MAX_ILIM_DUAL_CP_UA : MAX_ILIM_UA));
	/* ILIM less than min_ilim_ua, disable charging */
	if (ilim_uA < chip->min_ilim_ua) {
		smb1390_dbg(chip, PR_INFO, "ILIM %duA is too low to allow charging\n",
@@ -926,6 +979,7 @@ static void smb1390_status_change_work(struct work_struct *work)
	if (!is_psy_voter_available(chip))
		goto out;

	if (!smb1390_is_adapter_cc_mode(chip))
		vote(chip->disable_votable, SOC_LEVEL_VOTER,
		     smb1390_is_batt_soc_valid(chip) ? false : true, 0);

@@ -944,7 +998,14 @@ static void smb1390_status_change_work(struct work_struct *work)
			goto out;
		}

		/* Check for SOC threshold only once before enabling CP */
		vote(chip->disable_votable, SRC_VOTER, false, 0);
		if (!chip->batt_soc_validated) {
			vote(chip->disable_votable, SOC_LEVEL_VOTER,
				smb1390_is_batt_soc_valid(chip) ?
				false : true, 0);
			chip->batt_soc_validated = true;
		}

		if (pval.intval == POWER_SUPPLY_CP_WIRELESS) {
			vote(chip->ilim_votable, ICL_VOTER, false, 0);
@@ -1014,10 +1075,12 @@ static void smb1390_status_change_work(struct work_struct *work)
			}
		}
	} else {
		chip->batt_soc_validated = false;
		vote(chip->disable_votable, SRC_VOTER, true, 0);
		vote(chip->disable_votable, TAPER_END_VOTER, false, 0);
		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);
	}

out:
@@ -1025,11 +1088,39 @@ static void smb1390_status_change_work(struct work_struct *work)
	chip->status_change_running = false;
}

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;
		/*
		 * Set ILIM of master SMB1390 to Max value = 3.2A once slave is
		 * disabled to prevent ILIM irq storm.
		 */
		smb1390_dbg(chip, PR_INFO, "Set Master ILIM to MAX, post Slave disable in taper, fcc=%d\n",
									fcc_uA);
		vote_override(chip->ilim_votable, CC_MODE_VOTER,
						true, MAX_ILIM_DUAL_CP_UA);
	}

	return rc;
}

static void smb1390_taper_work(struct work_struct *work)
{
	struct smb1390 *chip = container_of(work, struct smb1390, taper_work);
	union power_supply_propval pval = {0, };
	int rc, fcc_uA;
	int rc, fcc_uA, delta_fcc_uA;

	if (!is_psy_voter_available(chip))
		goto out;
@@ -1053,11 +1144,21 @@ static void smb1390_taper_work(struct work_struct *work)
		}

		if (pval.intval == POWER_SUPPLY_CHARGE_TYPE_TAPER) {
			delta_fcc_uA =
				(smb1390_is_adapter_cc_mode(chip) ?
							CC_MODE_TAPER_DELTA_UA :
							DEFAULT_TAPER_DELTA_UA);
			fcc_uA = get_effective_result(chip->fcc_votable)
								- 100000;
								- delta_fcc_uA;
			smb1390_dbg(chip, PR_INFO, "taper work reducing FCC to %duA\n",
				fcc_uA);
			vote(chip->fcc_votable, CP_VOTER, true, fcc_uA);
			rc = smb1390_validate_slave_chg_taper(chip, fcc_uA);
			if (rc < 0) {
				pr_err("Couldn't Disable slave in Taper, rc=%d\n",
				       rc);
				goto out;
			}

			if (fcc_uA < (chip->min_ilim_ua * 2)) {
				vote(chip->disable_votable, TAPER_END_VOTER,
@@ -1174,10 +1275,7 @@ static int smb1390_get_prop(struct power_supply *psy,
			val->intval |= status;
		break;
	case POWER_SUPPLY_PROP_CP_ILIM:
		rc = smb1390_read(chip, CORE_FTRIM_ILIM_REG, &status);
		if (!rc)
			val->intval = ((status & CFG_ILIM_MASK) * 100000)
					+ 500000;
		rc = smb1390_get_cp_ilim(chip, val);
		break;
	case POWER_SUPPLY_PROP_CHIP_VERSION:
		val->intval = chip->pmic_rev_id->rev4;
@@ -1215,6 +1313,11 @@ static int smb1390_set_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CP_IRQ_STATUS:
		chip->irq_status = val->intval;
		break;
	case POWER_SUPPLY_PROP_CP_ILIM:
		if (chip->ilim_votable)
			vote_override(chip->ilim_votable, CC_MODE_VOTER,
							true, val->intval);
		break;
	default:
		smb1390_dbg(chip, PR_MISC, "charge pump power supply set prop %d not supported\n",
			prop);
@@ -1233,6 +1336,7 @@ static int smb1390_prop_is_writeable(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CP_IRQ_STATUS:
	case POWER_SUPPLY_PROP_INPUT_CURRENT_MAX:
	case POWER_SUPPLY_PROP_CURRENT_CAPABILITY:
	case POWER_SUPPLY_PROP_CP_ILIM:
		return 1;
	default:
		break;
@@ -1307,6 +1411,10 @@ static int smb1390_parse_dt(struct smb1390 *chip)
	chip->pl_output_mode = POWER_SUPPLY_PL_OUTPUT_VPH;
	of_property_read_u32(chip->dev->of_node, "qcom,parallel-output-mode",
			&chip->pl_output_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);
	return 0;
}

+13 −0
Original line number Diff line number Diff line
@@ -5483,6 +5483,12 @@ static void typec_src_removal(struct smb_charger *chg)
	chg->voltage_max_uv = MICRO_5V;
	chg->usbin_forced_max_uv = 0;

	/* Reset CC mode votes */
	vote(chg->fcc_main_votable, MAIN_FCC_VOTER, false, 0);
	chg->adapter_cc_mode = 0;
	vote_override(chg->fcc_votable, CC_MODE_VOTER, false, 0);
	vote_override(chg->usb_icl_votable, CC_MODE_VOTER, false, 0);

	/* write back the default FLOAT charger configuration */
	rc = smblib_masked_write(chg, USBIN_OPTIONS_2_CFG_REG,
				(u8)FLOAT_OPTIONS_MASK, chg->float_cfg);
@@ -6786,6 +6792,13 @@ static int smblib_create_votables(struct smb_charger *chg)
		return rc;
	}

	chg->fcc_main_votable = find_votable("FCC_MAIN");
	if (chg->fcc_main_votable == NULL) {
		rc = -EINVAL;
		smblib_err(chg, "Couldn't find FCC Main votable rc=%d\n", rc);
		return rc;
	}

	chg->fv_votable = find_votable("FV");
	if (chg->fv_votable == NULL) {
		rc = -EINVAL;
+18 −0
Original line number Diff line number Diff line
@@ -80,6 +80,8 @@ enum print_reason {
#define CHARGER_TYPE_VOTER		"CHARGER_TYPE_VOTER"
#define HDC_IRQ_VOTER			"HDC_IRQ_VOTER"
#define DETACH_DETECT_VOTER		"DETACH_DETECT_VOTER"
#define CC_MODE_VOTER			"CC_MODE_VOTER"
#define MAIN_FCC_VOTER			"MAIN_FCC_VOTER"

#define BOOST_BACK_STORM_COUNT	3
#define WEAK_CHG_STORM_COUNT	8
@@ -229,6 +231,17 @@ enum chg_term_config_src {
	ITERM_SRC_ANALOG
};

enum comp_clamp_levels {
	CLAMP_LEVEL_DEFAULT = 0,
	CLAMP_LEVEL_1,
	MAX_CLAMP_LEVEL,
};

struct clamp_config {
	u16 reg[3];
	u16 val[3];
};

struct smb_irq_info {
	const char			*name;
	const irq_handler_t		handler;
@@ -398,6 +411,9 @@ struct smb_charger {
	/* parallel charging */
	struct parallel_params	pl;

	/* CC Mode */
	int	adapter_cc_mode;

	/* regulators */
	struct smb_regulator	*vbus_vreg;
	struct smb_regulator	*vconn_vreg;
@@ -406,6 +422,7 @@ struct smb_charger {
	/* votables */
	struct votable		*dc_suspend_votable;
	struct votable		*fcc_votable;
	struct votable		*fcc_main_votable;
	struct votable		*fv_votable;
	struct votable		*usb_icl_votable;
	struct votable		*awake_votable;
@@ -526,6 +543,7 @@ struct smb_charger {
	int			dr_mode;
	int			usbin_forced_max_uv;
	int			init_thermal_ua;
	u32			comp_clamp_level;

	/* workaround flag */
	u32			wa_flags;