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

Commit 3002fe4f authored by Ashay Jaiswal's avatar Ashay Jaiswal
Browse files

power: smb1390: add support to disable smb1390 based on SOC



Charger driver disables SMB1390 once charging enters Taper charging
phase, this is to prevent SMB1390 from pumping high current into battery
at higher voltages. There are condition like adapter reset where SMB1390
might get enabled at higher battery voltage and pump current into the
battery before software gets chance to disable it and this could lead to
battery OV.
Fix this by by keeping SMB1390 disabled above a configured battery SOC.

Change-Id: Ibbac8b3775a0096599644a74306961996ba5daa7
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
parent 616762d4
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -48,6 +48,12 @@ Charger specific properties:
	      If this value is not specified or is not one of the above
	      then default value is 110.

- qcom,max-cutoff-soc
  Usage:      optional
  Value type: <u32>
  Definition: SOC beyond which SMB1390 is kept disabled.
	      If this value is not specified then default value is 85%.

================================================
Second Level Nodes - SMB1390 Charger Peripherals
================================================
+36 −0
Original line number Diff line number Diff line
@@ -96,6 +96,7 @@
#define WIRELESS_VOTER		"WIRELESS_VOTER"
#define SRC_VOTER		"SRC_VOTER"
#define SWITCHER_TOGGLE_VOTER	"SWITCHER_TOGGLE_VOTER"
#define SOC_LEVEL_VOTER		"SOC_LEVEL_VOTER"

#define THERMAL_SUSPEND_DECIDEGC	1400

@@ -178,6 +179,7 @@ struct smb1390 {
	u32			debug_mask;
	u32			min_ilim_ua;
	u32			max_temp_alarm_degc;
	u32			max_cutoff_soc;
};

struct smb_irq {
@@ -459,6 +461,28 @@ static int smb1390_get_isns(struct smb1390 *chip,
	return rc;
}

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

	if (!chip->batt_psy)
		goto out;

	rc = power_supply_get_property(chip->batt_psy,
			POWER_SUPPLY_PROP_CAPACITY, &pval);
	if (rc < 0) {
		pr_err("Couldn't get CAPACITY rc=%d\n", rc);
		goto out;
	}

	if (pval.intval >= chip->max_cutoff_soc)
		return false;

out:
	return true;
}

/* voter callbacks */
static int smb1390_disable_vote_cb(struct votable *votable, void *data,
				  int disable, const char *client)
@@ -558,6 +582,9 @@ static void smb1390_status_change_work(struct work_struct *work)
	if (!is_psy_voter_available(chip))
		goto out;

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

	rc = power_supply_get_property(chip->usb_psy,
			POWER_SUPPLY_PROP_SMB_EN_MODE, &pval);
	if (rc < 0) {
@@ -636,6 +663,7 @@ static void smb1390_status_change_work(struct work_struct *work)
		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);
	}

out:
@@ -903,6 +931,10 @@ static int smb1390_parse_dt(struct smb1390 *chip)
	of_property_read_u32(chip->dev->of_node, "qcom,max-temp-alarm-degc",
			&chip->max_temp_alarm_degc);

	chip->max_cutoff_soc = 85; /* 85% */
	of_property_read_u32(chip->dev->of_node, "qcom,max-cutoff-soc",
			&chip->max_cutoff_soc);

	return 0;
}

@@ -929,6 +961,9 @@ static int smb1390_create_votables(struct smb1390 *chip)
	 * traditional parallel charging if present
	 */
	vote(chip->disable_votable, USER_VOTER, true, 0);
	/* keep charge pump disabled if SOC is above threshold */
	vote(chip->disable_votable, SOC_LEVEL_VOTER,
			smb1390_is_batt_soc_valid(chip) ? false : true, 0);

	/*
	 * In case SMB1390 probe happens after FCC value has been configured,
@@ -1193,6 +1228,7 @@ static int smb1390_remove(struct platform_device *pdev)

	/* explicitly disable charging */
	vote(chip->disable_votable, USER_VOTER, true, 0);
	vote(chip->disable_votable, SOC_LEVEL_VOTER, true, 0);
	cancel_work(&chip->taper_work);
	cancel_work(&chip->status_change_work);
	wakeup_source_unregister(chip->cp_ws);