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

Commit 2f006f97 authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

power: qpnp-fg-gen3: support JEITA thresholds configurable runtime



Currently, JEITA thresholds are configured through the device
tree properties. Allow them to be configured runtime through
power supply properties.

Change-Id: Ie93c7e447a4f8ac793e6e324f7a0269dbc14c7e5
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 063d7870
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -104,7 +104,7 @@ enum sram_access_flags {
};

/* JEITA */
enum {
enum jeita_levels {
	JEITA_COLD = 0,
	JEITA_COOL,
	JEITA_WARM,
+145 −14
Original line number Diff line number Diff line
@@ -576,6 +576,41 @@ static int fg_get_charge_counter(struct fg_chip *chip, int *val)
	return 0;
}

static int fg_get_jeita_threshold(struct fg_chip *chip,
				enum jeita_levels level, int *temp_decidegC)
{
	int rc;
	u8 val;
	u16 reg;

	switch (level) {
	case JEITA_COLD:
		reg = BATT_INFO_JEITA_TOO_COLD(chip);
		break;
	case JEITA_COOL:
		reg = BATT_INFO_JEITA_COLD(chip);
		break;
	case JEITA_WARM:
		reg = BATT_INFO_JEITA_HOT(chip);
		break;
	case JEITA_HOT:
		reg = BATT_INFO_JEITA_TOO_HOT(chip);
		break;
	default:
		return -EINVAL;
	}

	rc = fg_read(chip, reg, &val, 1);
	if (rc < 0) {
		pr_err("Error in reading jeita level %d, rc=%d\n", level, rc);
		return rc;
	}

	/* Resolution is 0.5C. Base is -30C. */
	*temp_decidegC = (((5 * val) / 10) - 30) * 10;
	return 0;
}

#define BATT_TEMP_NUMR		1
#define BATT_TEMP_DENR		1
static int fg_get_battery_temp(struct fg_chip *chip, int *val)
@@ -978,12 +1013,6 @@ static int fg_get_batt_profile(struct fg_chip *chip)
	return 0;
}

static inline void get_temp_setpoint(int threshold, u8 *val)
{
	/* Resolution is 0.5C. Base is -30C. */
	*val = DIV_ROUND_CLOSEST((threshold + 30) * 10, 5);
}

static inline void get_batt_temp_delta(int delta, u8 *val)
{
	switch (delta) {
@@ -1863,6 +1892,44 @@ static int fg_rconn_config(struct fg_chip *chip)
	return 0;
}

static int fg_set_jeita_threshold(struct fg_chip *chip,
				enum jeita_levels level, int temp_decidegC)
{
	int rc;
	u8 val;
	u16 reg;

	if (temp_decidegC < -300 || temp_decidegC > 970)
		return -EINVAL;

	/* Resolution is 0.5C. Base is -30C. */
	val = DIV_ROUND_CLOSEST(((temp_decidegC / 10) + 30) * 10, 5);
	switch (level) {
	case JEITA_COLD:
		reg = BATT_INFO_JEITA_TOO_COLD(chip);
		break;
	case JEITA_COOL:
		reg = BATT_INFO_JEITA_COLD(chip);
		break;
	case JEITA_WARM:
		reg = BATT_INFO_JEITA_HOT(chip);
		break;
	case JEITA_HOT:
		reg = BATT_INFO_JEITA_TOO_HOT(chip);
		break;
	default:
		return -EINVAL;
	}

	rc = fg_write(chip, reg, &val, 1);
	if (rc < 0) {
		pr_err("Error in setting jeita level %d, rc=%d\n", level, rc);
		return rc;
	}

	return 0;
}

static int fg_set_constant_chg_voltage(struct fg_chip *chip, int volt_uv)
{
	u8 buf[2];
@@ -3377,6 +3444,34 @@ static int fg_psy_get_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_TEMP:
		rc = fg_get_battery_temp(chip, &pval->intval);
		break;
	case POWER_SUPPLY_PROP_COLD_TEMP:
		rc = fg_get_jeita_threshold(chip, JEITA_COLD, &pval->intval);
		if (rc < 0) {
			pr_err("Error in reading jeita_cold, rc=%d\n", rc);
			return rc;
		}
		break;
	case POWER_SUPPLY_PROP_COOL_TEMP:
		rc = fg_get_jeita_threshold(chip, JEITA_COOL, &pval->intval);
		if (rc < 0) {
			pr_err("Error in reading jeita_cool, rc=%d\n", rc);
			return rc;
		}
		break;
	case POWER_SUPPLY_PROP_WARM_TEMP:
		rc = fg_get_jeita_threshold(chip, JEITA_WARM, &pval->intval);
		if (rc < 0) {
			pr_err("Error in reading jeita_warm, rc=%d\n", rc);
			return rc;
		}
		break;
	case POWER_SUPPLY_PROP_HOT_TEMP:
		rc = fg_get_jeita_threshold(chip, JEITA_HOT, &pval->intval);
		if (rc < 0) {
			pr_err("Error in reading jeita_hot, rc=%d\n", rc);
			return rc;
		}
		break;
	case POWER_SUPPLY_PROP_RESISTANCE:
		rc = fg_get_battery_resistance(chip, &pval->intval);
		break;
@@ -3514,6 +3609,34 @@ static int fg_psy_set_property(struct power_supply *psy,
		if (rc < 0)
			pr_err("Error in saving learned_cc_uah, rc=%d\n", rc);
		break;
	case POWER_SUPPLY_PROP_COLD_TEMP:
		rc = fg_set_jeita_threshold(chip, JEITA_COLD, pval->intval);
		if (rc < 0) {
			pr_err("Error in writing jeita_cold, rc=%d\n", rc);
			return rc;
		}
		break;
	case POWER_SUPPLY_PROP_COOL_TEMP:
		rc = fg_set_jeita_threshold(chip, JEITA_COOL, pval->intval);
		if (rc < 0) {
			pr_err("Error in writing jeita_cool, rc=%d\n", rc);
			return rc;
		}
		break;
	case POWER_SUPPLY_PROP_WARM_TEMP:
		rc = fg_set_jeita_threshold(chip, JEITA_WARM, pval->intval);
		if (rc < 0) {
			pr_err("Error in writing jeita_warm, rc=%d\n", rc);
			return rc;
		}
		break;
	case POWER_SUPPLY_PROP_HOT_TEMP:
		rc = fg_set_jeita_threshold(chip, JEITA_HOT, pval->intval);
		if (rc < 0) {
			pr_err("Error in writing jeita_hot, rc=%d\n", rc);
			return rc;
		}
		break;
	default:
		break;
	}
@@ -3530,6 +3653,10 @@ static int fg_property_is_writeable(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CC_STEP:
	case POWER_SUPPLY_PROP_CC_STEP_SEL:
	case POWER_SUPPLY_PROP_CHARGE_FULL:
	case POWER_SUPPLY_PROP_COLD_TEMP:
	case POWER_SUPPLY_PROP_COOL_TEMP:
	case POWER_SUPPLY_PROP_WARM_TEMP:
	case POWER_SUPPLY_PROP_HOT_TEMP:
		return 1;
	default:
		break;
@@ -3571,6 +3698,10 @@ static int fg_notifier_cb(struct notifier_block *nb,
static enum power_supply_property fg_psy_props[] = {
	POWER_SUPPLY_PROP_CAPACITY,
	POWER_SUPPLY_PROP_TEMP,
	POWER_SUPPLY_PROP_COLD_TEMP,
	POWER_SUPPLY_PROP_COOL_TEMP,
	POWER_SUPPLY_PROP_WARM_TEMP,
	POWER_SUPPLY_PROP_HOT_TEMP,
	POWER_SUPPLY_PROP_VOLTAGE_NOW,
	POWER_SUPPLY_PROP_VOLTAGE_OCV,
	POWER_SUPPLY_PROP_CURRENT_NOW,
@@ -3749,29 +3880,29 @@ static int fg_hw_init(struct fg_chip *chip)
		}
	}

	get_temp_setpoint(chip->dt.jeita_thresholds[JEITA_COLD], &val);
	rc = fg_write(chip, BATT_INFO_JEITA_TOO_COLD(chip), &val, 1);
	rc = fg_set_jeita_threshold(chip, JEITA_COLD,
		chip->dt.jeita_thresholds[JEITA_COLD] * 10);
	if (rc < 0) {
		pr_err("Error in writing jeita_cold, rc=%d\n", rc);
		return rc;
	}

	get_temp_setpoint(chip->dt.jeita_thresholds[JEITA_COOL], &val);
	rc = fg_write(chip, BATT_INFO_JEITA_COLD(chip), &val, 1);
	rc = fg_set_jeita_threshold(chip, JEITA_COOL,
		chip->dt.jeita_thresholds[JEITA_COOL] * 10);
	if (rc < 0) {
		pr_err("Error in writing jeita_cool, rc=%d\n", rc);
		return rc;
	}

	get_temp_setpoint(chip->dt.jeita_thresholds[JEITA_WARM], &val);
	rc = fg_write(chip, BATT_INFO_JEITA_HOT(chip), &val, 1);
	rc = fg_set_jeita_threshold(chip, JEITA_WARM,
		chip->dt.jeita_thresholds[JEITA_WARM] * 10);
	if (rc < 0) {
		pr_err("Error in writing jeita_warm, rc=%d\n", rc);
		return rc;
	}

	get_temp_setpoint(chip->dt.jeita_thresholds[JEITA_HOT], &val);
	rc = fg_write(chip, BATT_INFO_JEITA_TOO_HOT(chip), &val, 1);
	rc = fg_set_jeita_threshold(chip, JEITA_HOT,
		chip->dt.jeita_thresholds[JEITA_HOT] * 10);
	if (rc < 0) {
		pr_err("Error in writing jeita_hot, rc=%d\n", rc);
		return rc;