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

Commit 3221c325 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 3f6a54bd 5f7bd35c
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -51,6 +51,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;
@@ -137,6 +139,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
@@ -1612,6 +1612,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, };
@@ -1942,6 +1990,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;
@@ -1997,6 +2051,8 @@ static enum power_supply_property qg_psy_props[] = {
	POWER_SUPPLY_PROP_CC_SOC,
	POWER_SUPPLY_PROP_FG_RESET,
	POWER_SUPPLY_PROP_VOLTAGE_AVG,
	POWER_SUPPLY_PROP_POWER_AVG,
	POWER_SUPPLY_PROP_POWER_NOW,
};

static const struct power_supply_desc qg_psy_desc = {
@@ -3419,6 +3475,8 @@ static void qg_create_debugfs(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;
@@ -3655,10 +3713,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,
@@ -3799,9 +3869,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;
}
@@ -3811,12 +3884,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);
@@ -3832,12 +3908,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);
	}
@@ -3850,9 +3929,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