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

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

Merge "power: qpnp-qg: Add support to display available power"

parents 70cbcdf3 d8fc5e41
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -342,6 +342,21 @@ First Level Node - QGAUGE device
	Value type: <bool>
	Definition: Boolean property to use S7 for PON OCV.

- qcom,min-sleep-time-secs
	Usage:      optional
	Value type: <u32>
	Definition: The minimum sleep time in secs to allow a SOC
		    jump if there has been a GOOD_OCV.

- qcom,qg-sys-min-voltage
	Usage:      optional
	Value type: <u32>
	Definition: The voltage threshold (in mV) which describes the system
		    minimum voltage as per the hardware recommendation. This
		    is not used for any configuration but only for calculating
		    the available power. If this property is not specified,
		    then the default value used is 2800 mV.

==========================================================
Second Level Nodes - Peripherals managed by QGAUGE driver
==========================================================
+3 −0
Original line number Diff line number Diff line
@@ -57,6 +57,8 @@ struct qg_dt {
	int			esr_disable_soc;
	int			esr_min_ibat_ua;
	int			shutdown_soc_threshold;
	int			min_sleep_time_secs;
	int			sys_min_volt_mv;
	bool			hold_soc_while_full;
	bool			linearize_soc;
	bool			cl_disable;
@@ -142,6 +144,7 @@ struct qpnp_qg {
	ktime_t			last_user_update_time;
	ktime_t			last_fifo_update_time;
	unsigned long		last_maint_soc_update_time;
	unsigned long		suspend_time;
	struct iio_channel	*batt_therm_chan;
	struct iio_channel	*batt_id_chan;

+86 −6
Original line number Diff line number Diff line
@@ -1579,6 +1579,54 @@ static int qg_get_charge_counter(struct qpnp_qg *chip, int *charge_counter)
	return 0;
}

static int qg_get_power(struct qpnp_qg *chip, int *val, bool average)
{
	int rc, v_min, v_ocv, rbatt = 0, esr = 0;
	s64 power;

	if (is_debug_batt_id(chip)) {
		*val = -EINVAL;
		return 0;
	}

	v_min = chip->dt.sys_min_volt_mv * 1000;

	rc = qg_sdam_read(SDAM_OCV_UV, &v_ocv);
	if (rc < 0) {
		pr_err("Failed to read OCV rc=%d\n", rc);
		return rc;
	}

	rc = qg_sdam_read(SDAM_RBAT_MOHM, &rbatt);
	if (rc < 0) {
		pr_err("Failed to read T_RBAT rc=%d\n", rc);
		return rc;
	}

	rbatt *= 1000;	/* uohms */
	esr = chip->esr_last * 1000;

	if (rbatt <= 0 || esr <= 0) {
		pr_debug("Invalid rbatt/esr rbatt=%d esr=%d\n", rbatt, esr);
		*val = -EINVAL;
		return 0;
	}

	power = (s64)v_min * (v_ocv - v_min);

	if (average)
		power = div_s64(power, rbatt);
	else
		power = div_s64(power, esr);

	*val = power;

	qg_dbg(chip, QG_DEBUG_STATUS, "v_min=%d v_ocv=%d rbatt=%d esr=%d power=%lld\n",
			v_min, v_ocv, rbatt, esr, power);

	return 0;
}

static int qg_get_ttf_param(void *data, enum ttf_param param, int *val)
{
	union power_supply_propval prop = {0, };
@@ -1909,6 +1957,12 @@ static int qg_psy_get_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
		rc = qg_get_vbat_avg(chip, &pval->intval);
		break;
	case POWER_SUPPLY_PROP_POWER_NOW:
		rc = qg_get_power(chip, &pval->intval, false);
		break;
	case POWER_SUPPLY_PROP_POWER_AVG:
		rc = qg_get_power(chip, &pval->intval, true);
		break;
	default:
		pr_debug("Unsupported property %d\n", psp);
		break;
@@ -1964,6 +2018,8 @@ static enum power_supply_property qg_psy_props[] = {
	POWER_SUPPLY_PROP_FG_RESET,
	POWER_SUPPLY_PROP_CC_SOC,
	POWER_SUPPLY_PROP_VOLTAGE_AVG,
	POWER_SUPPLY_PROP_POWER_AVG,
	POWER_SUPPLY_PROP_POWER_NOW,
};

static const struct power_supply_desc qg_psy_desc = {
@@ -3360,6 +3416,8 @@ static int qg_alg_init(struct qpnp_qg *chip)
#define DEFAULT_ESR_QUAL_VBAT_UV	7000
#define DEFAULT_ESR_DISABLE_SOC		1000
#define ESR_CHG_MIN_IBAT_UA		(-450000)
#define DEFAULT_SLEEP_TIME_SECS		1800 /* 30 mins */
#define DEFAULT_SYS_MIN_VOLT_MV		2800
static int qg_parse_dt(struct qpnp_qg *chip)
{
	int rc = 0;
@@ -3596,10 +3654,22 @@ static int qg_parse_dt(struct qpnp_qg *chip)
	else
		chip->dt.shutdown_soc_threshold = temp;

	rc = of_property_read_u32(node, "qcom,qg-sys-min-voltage", &temp);
	if (rc < 0)
		chip->dt.sys_min_volt_mv = DEFAULT_SYS_MIN_VOLT_MV;
	else
		chip->dt.sys_min_volt_mv = temp;

	chip->dt.qg_ext_sense = of_property_read_bool(node, "qcom,qg-ext-sns");

	chip->dt.use_s7_ocv = of_property_read_bool(node, "qcom,qg-use-s7-ocv");

	rc = of_property_read_u32(node, "qcom,min-sleep-time-secs", &temp);
	if (rc < 0)
		chip->dt.min_sleep_time_secs = DEFAULT_SLEEP_TIME_SECS;
	else
		chip->dt.min_sleep_time_secs = temp;

	/* Capacity learning params*/
	if (!chip->dt.cl_disable) {
		chip->dt.cl_feedback_on = of_property_read_bool(node,
@@ -3740,9 +3810,12 @@ static int process_suspend(struct qpnp_qg *chip)
		chip->suspend_data = true;
	}

	qg_dbg(chip, QG_DEBUG_PM, "FIFO rt_length=%d sleep_fifo_length=%d default_s2_count=%d suspend_data=%d\n",
	get_rtc_time(&chip->suspend_time);

	qg_dbg(chip, QG_DEBUG_PM, "FIFO rt_length=%d sleep_fifo_length=%d default_s2_count=%d suspend_data=%d time=%d\n",
			fifo_rt_length, sleep_fifo_length,
			chip->dt.s2_fifo_length, chip->suspend_data);
			chip->dt.s2_fifo_length, chip->suspend_data,
			chip->suspend_time);

	return rc;
}
@@ -3752,12 +3825,15 @@ static int process_resume(struct qpnp_qg *chip)
	u8 status2 = 0, rt_status = 0;
	u32 ocv_uv = 0, ocv_raw = 0;
	int rc;
	unsigned long rtc_sec = 0;
	unsigned long rtc_sec = 0, sleep_time_secs = 0;

	/* skip if profile is not loaded */
	if (!chip->profile_loaded)
		return 0;

	get_rtc_time(&rtc_sec);
	sleep_time_secs = rtc_sec - chip->suspend_time;

	rc = qg_read(chip, chip->qg_base + QG_STATUS2_REG, &status2, 1);
	if (rc < 0) {
		pr_err("Failed to read status2 register, rc=%d\n", rc);
@@ -3773,12 +3849,15 @@ static int process_resume(struct qpnp_qg *chip)

		 /* Clear suspend data as there has been a GOOD OCV */
		memset(&chip->kdata, 0, sizeof(chip->kdata));
		get_rtc_time(&rtc_sec);
		chip->kdata.fifo_time = (u32)rtc_sec;
		chip->kdata.param[QG_GOOD_OCV_UV].data = ocv_uv;
		chip->kdata.param[QG_GOOD_OCV_UV].valid = true;
		chip->suspend_data = false;

		/* allow SOC jump if we have slept longer */
		if (sleep_time_secs >= chip->dt.min_sleep_time_secs)
			chip->force_soc = true;

		qg_dbg(chip, QG_DEBUG_PM, "GOOD OCV @ resume good_ocv=%d uV\n",
				ocv_uv);
	}
@@ -3791,9 +3870,10 @@ static int process_resume(struct qpnp_qg *chip)
	}
	rt_status &= FIFO_UPDATE_DONE_INT_LAT_STS_BIT;

	qg_dbg(chip, QG_DEBUG_PM, "FIFO_DONE_STS=%d suspend_data=%d good_ocv=%d\n",
	qg_dbg(chip, QG_DEBUG_PM, "FIFO_DONE_STS=%d suspend_data=%d good_ocv=%d sleep_time=%d secs\n",
				!!rt_status, chip->suspend_data,
				chip->kdata.param[QG_GOOD_OCV_UV].valid);
				chip->kdata.param[QG_GOOD_OCV_UV].valid,
				sleep_time_secs);
	/*
	 * If this is not a wakeup from FIFO-done,
	 * process the data immediately if - we have data from