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

Commit c6fa242a authored by Ashay Jaiswal's avatar Ashay Jaiswal
Browse files

power: smb5: add support to configure JEITA threshold



Add support to read JEITA hard/soft ADC code from battery
profile and configure charger hardware.

Change-Id: Ic515e6f62316695f9fc228ba87be47937d418d84
Signed-off-by: default avatarAshay Jaiswal <ashayj@codeaurora.org>
parent 34d61ef0
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -106,6 +106,12 @@ Profile data node optional properties:
			     the low and high thresholds.
			The threshold values in range should be in ascending
			and shouldn't overlap. It support 8 ranges at max.
- qcom,jeita-soft-thresholds: A tuple entry to specify ADC code for battery's soft JEITA
				threshold.
				<SOFT_COLD_ADC_CODE, SOFT_HOT_ADC_CODE>.
- qcom,jeita-hard-thresholds: A tuple entry to specify ADC code for battery's hard JEITA
				threshold.
				<HARD_COLD_ADC_CODE, HARD_HOT_ADC_CODE>.

Profile data node required subnodes:
- qcom,fcc-temp-lut : An 1-dimensional lookup table node that encodes
@@ -170,6 +176,8 @@ qcom,palladium-batterydata {
	qcom,v-cutoff-uv = <3400000>;
	qcom,chg-term-ua = <100000>;
	qcom,batt-id-kohm = <75>;
	qcom,jeita-soft-thresholds = <0x3ecc 0x1bff>;
	qcom,jeita-hard-thresholds = <0x4aff 0x15aa>;
	qcom,step-chg-ranges = <3600000 4000000 3000000
				4001000 4200000 2800000
				4201000 4400000 2000000>;
+1 −4
Original line number Diff line number Diff line
@@ -174,10 +174,7 @@ Charger specific properties:
  Usage:      optional
  Value type: <phandle>
  Definition: Specifies the phandle of the node which contains the battery
		profiles supported on the device. This is only specified
		when step charging and sw-jeita configurations are desired
		to be get from these properties defined in battery profile:
		qcom,step-chg-ranges, qcom,jeita-fcc-ranges, qcom,jeita-fv-ranges.
		profiles supported on the device.

- qcom,flash-derating-soc
  Usage:      optional
+100 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/irq.h>
#include <linux/iio/consumer.h>
#include <linux/pmic-voter.h>
#include <linux/of_batterydata.h>
#include "smb5-lib.h"
#include "smb5-reg.h"
#include "battery.h"
@@ -597,6 +598,8 @@ static int smblib_notifier_call(struct notifier_block *nb,
			chg->bms_psy = psy;
		if (ev == PSY_EVENT_PROP_CHANGED)
			schedule_work(&chg->bms_update_work);
		if (!chg->jeita_configured)
			schedule_work(&chg->jeita_update_work);
	}

	if (!chg->pl.psy && !strcmp(psy->desc->name, "parallel")) {
@@ -3542,6 +3545,100 @@ static void smblib_pl_enable_work(struct work_struct *work)
	vote(chg->awake_votable, PL_DELAY_VOTER, false, 0);
}

#define JEITA_SOFT			0
#define JEITA_HARD			1
static int smblib_update_jeita(struct smb_charger *chg, u32 *thresholds,
								int type)
{
	int rc;
	u16 temp, base;

	base = CHGR_JEITA_THRESHOLD_BASE_REG(type);

	temp = thresholds[1] & 0xFFFF;
	temp = ((temp & 0xFF00) >> 8) | ((temp & 0xFF) << 8);
	rc = smblib_batch_write(chg, base, (u8 *)&temp, 2);
	if (rc < 0) {
		smblib_err(chg,
			"Couldn't configure Jeita %s hot threshold rc=%d\n",
			(type == JEITA_SOFT) ? "Soft" : "Hard", rc);
		return rc;
	}

	temp = thresholds[0] & 0xFFFF;
	temp = ((temp & 0xFF00) >> 8) | ((temp & 0xFF) << 8);
	rc = smblib_batch_write(chg, base + 2, (u8 *)&temp, 2);
	if (rc < 0) {
		smblib_err(chg,
			"Couldn't configure Jeita %s cold threshold rc=%d\n",
			(type == JEITA_SOFT) ? "Soft" : "Hard", rc);
		return rc;
	}

	smblib_dbg(chg, PR_MISC, "%s Jeita threshold configured\n",
				(type == JEITA_SOFT) ? "Soft" : "Hard");

	return 0;
}

static void jeita_update_work(struct work_struct *work)
{
	struct smb_charger *chg = container_of(work, struct smb_charger,
						jeita_update_work);
	struct device_node *node = chg->dev->of_node;
	struct device_node *batt_node, *pnode;
	union power_supply_propval val;
	int rc;
	u32 jeita_thresholds[2];

	batt_node = of_find_node_by_name(node, "qcom,battery-data");
	if (!batt_node) {
		smblib_err(chg, "Batterydata not available\n");
		goto out;
	}

	rc = power_supply_get_property(chg->bms_psy,
			POWER_SUPPLY_PROP_RESISTANCE_ID, &val);
	if (rc < 0) {
		smblib_err(chg, "Failed to get batt-id rc=%d\n", rc);
		goto out;
	}

	pnode = of_batterydata_get_best_profile(batt_node,
					val.intval / 1000, NULL);
	if (IS_ERR(pnode)) {
		rc = PTR_ERR(pnode);
		smblib_err(chg, "Failed to detect valid battery profile %d\n",
				rc);
		goto out;
	}

	rc = of_property_read_u32_array(pnode, "qcom,jeita-hard-thresholds",
				jeita_thresholds, 2);
	if (!rc) {
		rc = smblib_update_jeita(chg, jeita_thresholds, JEITA_HARD);
		if (rc < 0) {
			smblib_err(chg, "Couldn't configure Hard Jeita rc=%d\n",
					rc);
			goto out;
		}
	}

	rc = of_property_read_u32_array(pnode, "qcom,jeita-soft-thresholds",
				jeita_thresholds, 2);
	if (!rc) {
		rc = smblib_update_jeita(chg, jeita_thresholds, JEITA_SOFT);
		if (rc < 0) {
			smblib_err(chg, "Couldn't configure Soft Jeita rc=%d\n",
					rc);
			goto out;
		}
	}

out:
	chg->jeita_configured = true;
}

static int smblib_create_votables(struct smb_charger *chg)
{
	int rc = 0;
@@ -3654,6 +3751,7 @@ int smblib_init(struct smb_charger *chg)
	mutex_init(&chg->lock);
	INIT_WORK(&chg->bms_update_work, bms_update_work);
	INIT_WORK(&chg->pl_update_work, pl_update_work);
	INIT_WORK(&chg->jeita_update_work, jeita_update_work);
	INIT_DELAYED_WORK(&chg->clear_hdc_work, clear_hdc_work);
	INIT_DELAYED_WORK(&chg->icl_change_work, smblib_icl_change_work);
	INIT_DELAYED_WORK(&chg->pl_enable_work, smblib_pl_enable_work);
@@ -3663,6 +3761,7 @@ int smblib_init(struct smb_charger *chg)
	chg->fake_input_current_limited = -EINVAL;
	chg->fake_batt_status = -EINVAL;
	chg->sink_src_mode = UNATTACHED_MODE;
	chg->jeita_configured = false;

	switch (chg->mode) {
	case PARALLEL_MASTER:
@@ -3720,6 +3819,7 @@ int smblib_deinit(struct smb_charger *chg)
	switch (chg->mode) {
	case PARALLEL_MASTER:
		cancel_work_sync(&chg->bms_update_work);
		cancel_work_sync(&chg->jeita_update_work);
		cancel_work_sync(&chg->pl_update_work);
		cancel_delayed_work_sync(&chg->clear_hdc_work);
		cancel_delayed_work_sync(&chg->icl_change_work);
+2 −0
Original line number Diff line number Diff line
@@ -305,6 +305,7 @@ struct smb_charger {
	/* work */
	struct work_struct	bms_update_work;
	struct work_struct	pl_update_work;
	struct work_struct	jeita_update_work;
	struct delayed_work	ps_change_timeout_work;
	struct delayed_work	clear_hdc_work;
	struct delayed_work	icl_change_work;
@@ -352,6 +353,7 @@ struct smb_charger {
	int			hw_max_icl_ua;
	int			auto_recharge_soc;
	enum sink_src_mode	sink_src_mode;
	bool			jeita_configured;

	/* workaround flag */
	u32			wa_flags;
+1 −0
Original line number Diff line number Diff line
@@ -101,6 +101,7 @@ enum {
#define JEITA_CCCOMP_CFG_HOT_REG		(CHGR_BASE + 0x92)
#define JEITA_CCCOMP_CFG_COLD_REG		(CHGR_BASE + 0x93)

#define CHGR_JEITA_THRESHOLD_BASE_REG(i)	(CHGR_BASE + 0x94 + (i * 4))
/********************************
 *  DCDC Peripheral Registers  *
 ********************************/