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

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

Merge "dt-bindings: qpnp-qg: Add documentation for FVSS"

parents 4e272866 b7a9474f
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -404,6 +404,20 @@ First Level Node - QGAUGE device
		    'qcom,qg-fast-chg-config' is enabled. The
		    default value if not specified is 1.

- qcom,fvss-enable
	Usage:      optional
	Value type: bool
	Definition: Enable Filtered Voltage based SOC scaling.
		    This logic enables SOC scaling to report
		    0 at the cutoff voltage.

- qcom,fvss-vbatt-mv
	Usage:      optional
	Value type: <u32>
	Definition: Battery voltage threshold at which FVSS is
		    enabled. Applicable only if 'qcom,fvss-enable'
		    is set.

==========================================================
Second Level Nodes - Peripherals managed by QGAUGE driver
==========================================================
+7 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ struct qg_dt {
	int			shutdown_soc_threshold;
	int			min_sleep_time_secs;
	int			sys_min_volt_mv;
	int			fvss_vbat_mv;
	bool			hold_soc_while_full;
	bool			linearize_soc;
	bool			cl_disable;
@@ -73,6 +74,7 @@ struct qg_dt {
	bool			use_s7_ocv;
	bool			qg_sleep_config;
	bool			qg_fast_chg_cfg;
	bool			fvss_enable;
};

struct qg_esr_data {
@@ -134,6 +136,7 @@ struct qpnp_qg {
	bool			dc_present;
	bool			charge_full;
	bool			force_soc;
	bool			fvss_active;
	int			charge_status;
	int			charge_type;
	int			chg_iterm_ma;
@@ -142,6 +145,8 @@ struct qpnp_qg {
	int			esr_nominal;
	int			soh;
	int			soc_reporting_ready;
	int			last_fifo_v_uv;
	int			last_fifo_i_ua;
	u32			fifo_done_count;
	u32			wa_flags;
	u32			seq_no;
@@ -150,6 +155,8 @@ struct qpnp_qg {
	u32			esr_last;
	u32			s2_state;
	u32			s2_state_mask;
	u32			soc_fvss_entry;
	u32			vbat_fvss_entry;
	ktime_t			last_user_update_time;
	ktime_t			last_fifo_update_time;
	unsigned long		last_maint_soc_update_time;
+91 −2
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "qg-reg.h"
#include "qg-util.h"
#include "qg-defs.h"
#include "qg-profile-lib.h"
#include "qg-soc.h"

#define DEFAULT_UPDATE_TIME_MS			64000
@@ -36,6 +37,11 @@ module_param_named(
	soc_interval_ms, qg_delta_soc_interval_ms, int, 0600
);

static int qg_fvss_delta_soc_interval_ms = 10000;
module_param_named(
	fvss_soc_interval_ms, qg_fvss_delta_soc_interval_ms, int, 0600
);

static int qg_delta_soc_cold_interval_ms = 4000;
module_param_named(
	soc_cold_interval_ms, qg_delta_soc_cold_interval_ms, int, 0600
@@ -46,6 +52,84 @@ module_param_named(
	maint_soc_update_ms, qg_maint_soc_update_ms, int, 0600
);

/* FVSS scaling only based on VBAT */
static int qg_fvss_vbat_scaling = 1;
module_param_named(
	fvss_vbat_scaling, qg_fvss_vbat_scaling, int, 0600
);

static int qg_process_fvss_soc(struct qpnp_qg *chip, int sys_soc)
{
	int rc, vbat_uv = 0, vbat_cutoff_uv = chip->dt.vbatt_cutoff_mv * 1000;
	int soc_vbat = 0, wt_vbat = 0, wt_sys = 0, soc_fvss = 0;

	if (!chip->dt.fvss_enable)
		return 0;

	if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING)
		goto exit_soc_scale;

	rc = qg_get_battery_voltage(chip, &vbat_uv);
	if (rc < 0)
		goto exit_soc_scale;

	if (!chip->last_fifo_v_uv)
		chip->last_fifo_v_uv = vbat_uv;

	if (chip->last_fifo_v_uv > (chip->dt.fvss_vbat_mv * 1000)) {
		qg_dbg(chip, QG_DEBUG_SOC, "FVSS: last_fifo_v=%d fvss_entry_uv=%d - exit\n",
			chip->last_fifo_v_uv, chip->dt.fvss_vbat_mv * 1000);
		goto exit_soc_scale;
	}

	/* Enter FVSS */
	if (!chip->fvss_active) {
		chip->vbat_fvss_entry = CAP(vbat_cutoff_uv,
					chip->dt.fvss_vbat_mv * 1000,
					chip->last_fifo_v_uv);
		chip->soc_fvss_entry = sys_soc;
		chip->fvss_active = true;
	} else if (chip->last_fifo_v_uv > chip->vbat_fvss_entry) {
		/* VBAT has gone beyond the entry voltage */
		chip->vbat_fvss_entry = chip->last_fifo_v_uv;
		chip->soc_fvss_entry = sys_soc;
	}

	soc_vbat = qg_linear_interpolate(chip->soc_fvss_entry,
					chip->vbat_fvss_entry,
					0,
					vbat_cutoff_uv,
					chip->last_fifo_v_uv);
	soc_vbat = CAP(0, 100, soc_vbat);

	if (qg_fvss_vbat_scaling) {
		wt_vbat = 100;
		wt_sys = 0;
	} else {
		wt_sys = qg_linear_interpolate(100,
					chip->soc_fvss_entry,
					0,
					0,
					sys_soc);
		wt_sys = CAP(0, 100, wt_sys);
		wt_vbat = 100 - wt_sys;
	}

	soc_fvss = ((soc_vbat * wt_vbat) + (sys_soc * wt_sys)) / 100;
	soc_fvss = CAP(0, 100, soc_fvss);

	qg_dbg(chip, QG_DEBUG_SOC, "FVSS: vbat_fvss_entry=%d soc_fvss_entry=%d cutoff_uv=%d vbat_uv=%d fifo_avg_v=%d soc_vbat=%d sys_soc=%d wt_vbat=%d wt_sys=%d soc_fvss=%d\n",
			chip->vbat_fvss_entry, chip->soc_fvss_entry,
			vbat_cutoff_uv, vbat_uv, chip->last_fifo_v_uv,
			soc_vbat, sys_soc, wt_vbat, wt_sys, soc_fvss);

	return soc_fvss;

exit_soc_scale:
	chip->fvss_active = false;
	return sys_soc;
}

int qg_adjust_sys_soc(struct qpnp_qg *chip)
{
	int soc, vbat_uv, rc;
@@ -72,8 +156,11 @@ int qg_adjust_sys_soc(struct qpnp_qg *chip)
		soc = DIV_ROUND_CLOSEST(chip->sys_soc, 100);
	}

	qg_dbg(chip, QG_DEBUG_SOC, "last_adj_sys_soc=%d  adj_sys_soc=%d\n",
					chip->last_adj_ssoc, soc);
	qg_dbg(chip, QG_DEBUG_SOC, "sys_soc=%d adjusted sys_soc=%d\n",
					chip->sys_soc, soc);

	soc = qg_process_fvss_soc(chip, soc);

	chip->last_adj_ssoc = soc;

	return soc;
@@ -103,6 +190,8 @@ static void get_next_update_time(struct qpnp_qg *chip)
	else if (chip->maint_soc > 0 && chip->maint_soc >= chip->recharge_soc)
		/* if in maintenance mode scale slower */
		min_delta_soc_interval_ms = qg_maint_soc_update_ms;
	else if (chip->fvss_active)
		min_delta_soc_interval_ms = qg_fvss_delta_soc_interval_ms;

	if (!min_delta_soc_interval_ms)
		min_delta_soc_interval_ms = 1000;	/* 1 second */
+23 −0
Original line number Diff line number Diff line
@@ -460,6 +460,9 @@ static int qg_process_fifo(struct qpnp_qg *chip, u32 fifo_length)
		chip->kdata.fifo[j].interval = sample_interval;
		chip->kdata.fifo[j].count = sample_count;

		chip->last_fifo_v_uv = chip->kdata.fifo[j].v;
		chip->last_fifo_i_ua = chip->kdata.fifo[j].i;

		qg_dbg(chip, QG_DEBUG_FIFO, "FIFO %d raw_v=%d uV=%d raw_i=%d uA=%d interval=%d count=%d\n",
					j, fifo_v,
					chip->kdata.fifo[j].v,
@@ -524,6 +527,9 @@ static int qg_process_accumulator(struct qpnp_qg *chip)
	if (chip->kdata.fifo_length == MAX_FIFO_LENGTH)
		chip->kdata.fifo_length = MAX_FIFO_LENGTH - 1;

	chip->last_fifo_v_uv = chip->kdata.fifo[index].v;
	chip->last_fifo_i_ua = chip->kdata.fifo[index].i;

	if (chip->kdata.fifo_length == 1)	/* Only accumulator data */
		chip->kdata.seq_no = chip->seq_no++ % U32_MAX;

@@ -2068,6 +2074,9 @@ static int qg_psy_get_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_POWER_AVG:
		rc = qg_get_power(chip, &pval->intval, true);
		break;
	case POWER_SUPPLY_PROP_SCALE_MODE_EN:
		pval->intval = chip->fvss_active;
		break;
	default:
		pr_debug("Unsupported property %d\n", psp);
		break;
@@ -2126,6 +2135,7 @@ static enum power_supply_property qg_psy_props[] = {
	POWER_SUPPLY_PROP_VOLTAGE_AVG,
	POWER_SUPPLY_PROP_POWER_AVG,
	POWER_SUPPLY_PROP_POWER_NOW,
	POWER_SUPPLY_PROP_SCALE_MODE_EN,
};

static const struct power_supply_desc qg_psy_desc = {
@@ -3601,6 +3611,7 @@ static int qg_alg_init(struct qpnp_qg *chip)
#define DEFAULT_SLEEP_TIME_SECS		1800 /* 30 mins */
#define DEFAULT_SYS_MIN_VOLT_MV		2800
#define DEFAULT_FAST_CHG_S2_FIFO_LENGTH	1
#define DEFAULT_FVSS_VBAT_MV		3500
static int qg_parse_dt(struct qpnp_qg *chip)
{
	int rc = 0;
@@ -3895,6 +3906,18 @@ static int qg_parse_dt(struct qpnp_qg *chip)
	else
		chip->dt.min_sleep_time_secs = temp;

	if (of_property_read_bool(node, "qcom,fvss-enable")) {

		chip->dt.fvss_enable = true;

		rc = of_property_read_u32(node,
				"qcom,fvss-vbatt-mv", &temp);
		if (rc < 0)
			chip->dt.fvss_vbat_mv = DEFAULT_FVSS_VBAT_MV;
		else
			chip->dt.fvss_vbat_mv = temp;
	}

	/* Capacity learning params*/
	if (!chip->dt.cl_disable) {
		chip->dt.cl_feedback_on = of_property_read_bool(node,