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

Commit d90944f6 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: qpnp-smb5: Add VBAT and SOC based recharge support" into msm-4.14

parents 1243fc2c 5a54d60d
Loading
Loading
Loading
Loading
+12 −4
Original line number Diff line number Diff line
@@ -109,10 +109,18 @@ Charger specific properties:

- qcom,auto-recharge-soc
  Usage:      optional
  Value type: <empty>
  Definition: Specifies if automatic recharge needs to be based off battery
		SOC. If this property is not specified, then auto recharge will
		be based off battery voltage.
  Value type: <u32>
  Definition: Specifies the SOC threshold at which the charger will
		restart charging after termination. The value specified
		ranges from 0 - 100. The feature is enabled if this
		property is specified with a valid SOC value.

- qcom,auto-recharge-vbat-mv
  Usage:      optional
  Value type: <u32>
  Definition: Specifies the battery voltage threshold at which the charger
		will restart charging after termination. The value specified
		is in milli-volts.

- qcom,suspend-input-on-debug-batt
  Usage:      optional
+78 −7
Original line number Diff line number Diff line
@@ -158,7 +158,8 @@ struct smb_dt_props {
	int			chg_inhibit_thr_mv;
	bool			no_battery;
	bool			hvdcp_disable;
	bool			auto_recharge_soc;
	int			auto_recharge_soc;
	int			auto_recharge_vbat_mv;
	int			wd_bark_time;
	int			batt_profile_fcc_ua;
	int			batt_profile_fv_uv;
@@ -329,8 +330,23 @@ static int smb5_parse_dt(struct smb5 *chip)
		return -EINVAL;
	}

	chip->dt.auto_recharge_soc = of_property_read_bool(node,
						"qcom,auto-recharge-soc");
	chip->dt.auto_recharge_soc = -EINVAL;
	rc = of_property_read_u32(node, "qcom,auto-recharge-soc",
				&chip->dt.auto_recharge_soc);
	if (!rc && (chip->dt.auto_recharge_soc < 0 ||
			chip->dt.auto_recharge_soc > 100)) {
		pr_err("qcom,auto-recharge-soc is incorrect\n");
		return -EINVAL;
	}
	chg->auto_recharge_soc = chip->dt.auto_recharge_soc;

	chip->dt.auto_recharge_vbat_mv = -EINVAL;
	rc = of_property_read_u32(node, "qcom,auto-recharge-vbat-mv",
				&chip->dt.auto_recharge_vbat_mv);
	if (!rc && (chip->dt.auto_recharge_vbat_mv < 0)) {
		pr_err("qcom,auto-recharge-vbat-mv is incorrect\n");
		return -EINVAL;
	}

	chg->dcp_icl_ua = chip->dt.usb_icl_ua;

@@ -956,6 +972,7 @@ static enum power_supply_property smb5_batt_props[] = {
	POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
	POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
	POWER_SUPPLY_PROP_CHARGE_COUNTER,
	POWER_SUPPLY_PROP_RECHARGE_SOC,
};

static int smb5_batt_get_prop(struct power_supply *psy,
@@ -1045,6 +1062,9 @@ static int smb5_batt_get_prop(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
		rc = smblib_get_prop_batt_charge_counter(chg, val);
		break;
	case POWER_SUPPLY_PROP_RECHARGE_SOC:
		val->intval = chg->auto_recharge_soc;
		break;
	default:
		pr_err("batt power supply prop %d not supported\n", psp);
		return -EINVAL;
@@ -1555,14 +1575,65 @@ static int smb5_init_hw(struct smb5 *chip)
		return rc;
	}

	rc = smblib_masked_write(chg, CHGR_CFG2_REG,
			SOC_BASED_RECHG_BIT,
			chip->dt.auto_recharge_soc ? SOC_BASED_RECHG_BIT : 0);
	rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK,
				(chip->dt.auto_recharge_vbat_mv != -EINVAL) ?
				VBAT_BASED_RECHG_BIT : 0);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure VBAT-rechg CHG_CFG2_REG rc=%d\n",
			rc);
		return rc;
	}

	/* program the auto-recharge VBAT threshold */
	if (chip->dt.auto_recharge_vbat_mv != -EINVAL) {
		u32 temp = VBAT_TO_VRAW_ADC(chip->dt.auto_recharge_vbat_mv);

		temp = ((temp & 0xFF00) >> 8) | ((temp & 0xFF) << 8);
		rc = smblib_batch_write(chg,
			CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG, (u8 *)&temp, 2);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure ADC_RECHARGE_THRESHOLD REG rc=%d\n",
				rc);
			return rc;
		}
		/* Program the sample count for VBAT based recharge to 3 */
		rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG,
					NO_OF_SAMPLE_FOR_RCHG,
					2 << NO_OF_SAMPLE_FOR_RCHG_SHIFT);
		if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure FG_UPDATE_CFG2_SEL_REG rc=%d\n",
			dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n",
				rc);
			return rc;
		}
	}

	rc = smblib_masked_write(chg, CHGR_CFG2_REG, RECHG_MASK,
				(chip->dt.auto_recharge_soc != -EINVAL) ?
				SOC_BASED_RECHG_BIT : VBAT_BASED_RECHG_BIT);
	if (rc < 0) {
		dev_err(chg->dev, "Couldn't configure SOC-rechg CHG_CFG2_REG rc=%d\n",
			rc);
		return rc;
	}

	/* program the auto-recharge threshold */
	if (chip->dt.auto_recharge_soc != -EINVAL) {
		rc = smblib_write(chg, CHARGE_RCHG_SOC_THRESHOLD_CFG_REG,
				(chip->dt.auto_recharge_soc * 255) / 100);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure CHG_RCHG_SOC_REG rc=%d\n",
				rc);
			return rc;
		}
		/* Program the sample count for SOC based recharge to 1 */
		rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG,
						NO_OF_SAMPLE_FOR_RCHG, 0);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n",
				rc);
			return rc;
		}
	}

	if (chg->sw_jeita_enabled) {
		rc = smblib_disable_hw_jeita(chg, true);
+6 −2
Original line number Diff line number Diff line
@@ -62,11 +62,15 @@ int smblib_write(struct smb_charger *chg, u16 addr, u8 val)
	return regmap_write(chg->regmap, addr, val);
}

int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val)
int smblib_batch_write(struct smb_charger *chg, u16 addr, u8 *val,
			int count)
{
	return regmap_bulk_write(chg->regmap, addr, val, count);
}

int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val)
{
	return regmap_update_bits(chg->regmap, addr, mask, val);

}

int smblib_get_jeita_cc_delta(struct smb_charger *chg, int *cc_delta_ua)
+5 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ enum print_reason {
#define BOOST_BACK_STORM_COUNT	3
#define WEAK_CHG_STORM_COUNT	8

#define VBAT_TO_VRAW_ADC(v)		div_u64((u64)v * 1000000UL, 194637UL)

enum smb_mode {
	PARALLEL_MASTER = 0,
	PARALLEL_SLAVE,
@@ -344,6 +346,7 @@ struct smb_charger {
	bool			use_extcon;
	bool			otg_present;
	int			hw_max_icl_ua;
	int			auto_recharge_soc;

	/* workaround flag */
	u32			wa_flags;
@@ -372,6 +375,8 @@ struct smb_charger {
int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
int smblib_masked_write(struct smb_charger *chg, u16 addr, u8 mask, u8 val);
int smblib_write(struct smb_charger *chg, u16 addr, u8 val);
int smblib_batch_write(struct smb_charger *chg, u16 addr, u8 *val, int count);
int smblib_batch_read(struct smb_charger *chg, u16 addr, u8 *val, int count);

int smblib_get_charge_param(struct smb_charger *chg,
			    struct smb_chg_param *param, int *val_u);
+13 −1
Original line number Diff line number Diff line
@@ -66,11 +66,17 @@ enum {
#define CHARGING_ENABLE_CMD_BIT			BIT(0)

#define CHGR_CFG2_REG				(CHGR_BASE + 0x51)
#define SOC_BASED_RECHG_BIT			BIT(1)
#define RECHG_MASK				GENMASK(2, 1)
#define VBAT_BASED_RECHG_BIT			BIT(2)
#define SOC_BASED_RECHG_BIT			GENMASK(2, 1)
#define CHARGER_INHIBIT_BIT			BIT(0)

#define CHGR_FAST_CHARGE_CURRENT_CFG_REG	(CHGR_BASE + 0x61)

#define CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG	(CHGR_BASE + 0x6B)
#define NO_OF_SAMPLE_FOR_RCHG_SHIFT		2
#define NO_OF_SAMPLE_FOR_RCHG			GENMASK(3, 2)

#define CHGR_FLOAT_VOLTAGE_CFG_REG		(CHGR_BASE + 0x70)

#define CHARGE_INHIBIT_THRESHOLD_CFG_REG	(CHGR_BASE + 0x72)
@@ -80,6 +86,12 @@ enum {
#define INHIBIT_ANALOG_VFLT_MINUS_200MV		2
#define INHIBIT_ANALOG_VFLT_MINUS_300MV		3

#define CHARGE_RCHG_SOC_THRESHOLD_CFG_REG	(CHGR_BASE + 0x7D)

#define CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG	(CHGR_BASE + 0x7E)

#define CHGR_ADC_RECHARGE_THRESHOLD_LSB_REG	(CHGR_BASE + 0x7F)

#define JEITA_EN_CFG_REG			(CHGR_BASE + 0x90)
#define JEITA_EN_HOT_SL_FCV_BIT			BIT(3)
#define JEITA_EN_COLD_SL_FCV_BIT		BIT(2)