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

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

Merge "power: smb5: Configure termination current thresholds"

parents e2cf1284 b051831f
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -124,6 +124,27 @@ Charger specific properties:
		then charge inhibit will be disabled by default.
		Allowed values are: 50, 100, 200, 300.

- qcom,chg-term-src
  Usage:      optional
  Value type: <u32>
  Definition: Specify either the ADC or analog comparators to be used in order
		to set threshold values for charge termination current.
		0 - Unspecified
		1 - Select ADC comparator
		2 - Select ANALOG comparator

- qcom,chg-term-current-ma
  Usage:      optional
  Value type: <u32>
  Definition: When ADC comparator is selected as qcom,chg-term-src, this
		parameter should be set to the desired upper threshold.

- qcom,chg-term-base-current-ma
  Usage:      optional
  Value type: <u32>
  Definition: When ADC comparator is selected as qcom,chg-term-src, this
		parameter should be set to the desired lower threshold.

- qcom,auto-recharge-soc
  Usage:      optional
  Value type: <u32>
+94 −2
Original line number Diff line number Diff line
@@ -179,6 +179,9 @@ struct smb_dt_props {
	int			wd_bark_time;
	int			batt_profile_fcc_ua;
	int			batt_profile_fv_uv;
	int			term_current_src;
	int			term_current_thresh_hi_ma;
	int			term_current_thresh_lo_ma;
};

struct smb5 {
@@ -328,6 +331,18 @@ static int smb5_parse_dt(struct smb5 *chip)
	if (rc < 0)
		chg->otg_cl_ua = MICRO_1P5A;

	rc = of_property_read_u32(node, "qcom,chg-term-src",
			&chip->dt.term_current_src);
	if (rc < 0)
		chip->dt.term_current_src = ITERM_SRC_UNSPECIFIED;

	rc = of_property_read_u32(node, "qcom,chg-term-current-ma",
			&chip->dt.term_current_thresh_hi_ma);

	if (chip->dt.term_current_src == ITERM_SRC_ADC)
		rc = of_property_read_u32(node, "qcom,chg-term-base-current-ma",
				&chip->dt.term_current_thresh_lo_ma);

	if (of_find_property(node, "qcom,thermal-mitigation", &byte_len)) {
		chg->thermal_mitigation = devm_kzalloc(chg->dev, byte_len,
			GFP_KERNEL);
@@ -1039,6 +1054,7 @@ static enum power_supply_property smb5_batt_props[] = {
	POWER_SUPPLY_PROP_VOLTAGE_MAX,
	POWER_SUPPLY_PROP_CURRENT_NOW,
	POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
	POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
	POWER_SUPPLY_PROP_TEMP,
	POWER_SUPPLY_PROP_TECHNOLOGY,
	POWER_SUPPLY_PROP_STEP_CHARGING_ENABLED,
@@ -1122,6 +1138,9 @@ static int smb5_batt_get_prop(struct power_supply *psy,
		val->intval = get_client_vote(chg->fcc_votable,
					      BATT_PROFILE_VOTER);
		break;
	case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
		rc = smblib_get_prop_batt_iterm(chg, val);
		break;
	case POWER_SUPPLY_PROP_TEMP:
		rc = smblib_get_prop_batt_temp(chg, val);
		break;
@@ -1456,6 +1475,71 @@ static int smb5_configure_micro_usb(struct smb_charger *chg)
	return rc;
}

static int smb5_configure_iterm_thresholds_adc(struct smb5 *chip)
{
	int rc = 0;
	int raw_hi_thresh, raw_lo_thresh;
	struct smb_charger *chg = &chip->chg;

	if (chip->dt.term_current_thresh_hi_ma < -10000 ||
			chip->dt.term_current_thresh_hi_ma > 10000 ||
			chip->dt.term_current_thresh_lo_ma < -10000 ||
			chip->dt.term_current_thresh_lo_ma > 10000) {
		dev_err(chg->dev, "ITERM threshold out of range rc=%d\n", rc);
		return -EINVAL;
	}

	/*
	 * Conversion:
	 * raw (A) = (scaled_mA * ADC_CHG_TERM_MASK) / (10 * 1000)
	 */

	if (chip->dt.term_current_thresh_hi_ma) {
		raw_hi_thresh = ((chip->dt.term_current_thresh_hi_ma *
						ADC_CHG_TERM_MASK) / 10000);
		raw_hi_thresh = sign_extend32(raw_hi_thresh, 15);

		rc = smblib_batch_write(chg, CHGR_ADC_ITERM_UP_THD_MSB_REG,
				(u8 *)&raw_hi_thresh, 2);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure ITERM threshold HIGH rc=%d\n",
					rc);
			return rc;
		}
	}

	if (chip->dt.term_current_thresh_lo_ma) {
		raw_lo_thresh = ((chip->dt.term_current_thresh_lo_ma *
					ADC_CHG_TERM_MASK) / 10000);
		raw_lo_thresh = sign_extend32(raw_lo_thresh, 15);

		rc = smblib_batch_write(chg, CHGR_ADC_ITERM_LO_THD_MSB_REG,
				(u8 *)&raw_lo_thresh, 2);
		if (rc < 0) {
			dev_err(chg->dev, "Couldn't configure ITERM threshold LOW rc=%d\n",
					rc);
			return rc;
		}
	}

	return rc;
}

static int smb5_configure_iterm_thresholds(struct smb5 *chip)
{
	int rc = 0;

	switch (chip->dt.term_current_src) {
	case ITERM_SRC_ADC:
		rc = smb5_configure_iterm_thresholds_adc(chip);
		break;
	default:
		break;
	}

	return rc;
}

static int smb5_init_hw(struct smb5 *chip)
{
	struct smb_charger *chg = &chip->chg;
@@ -1622,6 +1706,14 @@ static int smb5_init_hw(struct smb5 *chip)
		return rc;
	}

	/* set termination current threshold values */
	rc = smb5_configure_iterm_thresholds(chip);
	if (rc < 0) {
		pr_err("Couldn't configure ITERM thresholds rc=%d\n",
				rc);
		return rc;
	}

	/* configure float charger options */
	switch (chip->dt.float_option) {
	case FLOAT_DCP:
+39 −0
Original line number Diff line number Diff line
@@ -1471,6 +1471,45 @@ int smblib_get_prop_batt_current_now(struct smb_charger *chg,
	return rc;
}

int smblib_get_prop_batt_iterm(struct smb_charger *chg,
		union power_supply_propval *val)
{
	int rc, temp;
	u8 stat;

	/*
	 * Currently, only ADC comparator-based termination is supported,
	 * hence read only the threshold corresponding to ADC source.
	 * Proceed only if CHGR_ITERM_USE_ANALOG_BIT is 0.
	 */
	rc = smblib_read(chg, CHGR_ENG_CHARGING_CFG_REG, &stat);
	if (rc < 0) {
		smblib_err(chg, "Couldn't read CHGR_ENG_CHARGING_CFG_REG rc=%d\n",
				rc);
		return rc;
	}

	if (stat & CHGR_ITERM_USE_ANALOG_BIT) {
		val->intval = -EINVAL;
		return 0;
	}

	rc = smblib_batch_read(chg, CHGR_ADC_ITERM_UP_THD_MSB_REG,
			(u8 *)&temp, 2);

	if (rc < 0) {
		smblib_err(chg, "Couldn't read CHGR_ADC_ITERM_UP_THD_MSB_REG rc=%d\n",
				rc);
		return rc;
	}

	temp = sign_extend32(temp, 15);
	temp = DIV_ROUND_CLOSEST(temp * 10000, ADC_CHG_TERM_MASK);
	val->intval = temp;

	return rc;
}

int smblib_get_prop_batt_temp(struct smb_charger *chg,
			      union power_supply_propval *val)
{
+10 −0
Original line number Diff line number Diff line
@@ -72,6 +72,8 @@ enum print_reason {

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

#define ADC_CHG_TERM_MASK	32767

enum smb_mode {
	PARALLEL_MASTER = 0,
	PARALLEL_SLAVE,
@@ -171,6 +173,12 @@ enum float_options {
	SUSPEND_INPUT		= 4,
};

enum chg_term_config_src {
	ITERM_SRC_UNSPECIFIED,
	ITERM_SRC_ADC,
	ITERM_SRC_ANALOG
};

struct smb_irq_info {
	const char			*name;
	const irq_handler_t		handler;
@@ -459,6 +467,8 @@ int smblib_get_prop_batt_voltage_now(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_get_prop_batt_current_now(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_get_prop_batt_iterm(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_get_prop_batt_temp(struct smb_charger *chg,
				union power_supply_propval *val);
int smblib_get_prop_batt_charge_counter(struct smb_charger *chg,
+9 −0
Original line number Diff line number Diff line
@@ -73,6 +73,11 @@ enum {

#define CHGR_FAST_CHARGE_CURRENT_CFG_REG	(CHGR_BASE + 0x61)

#define CHGR_ADC_ITERM_UP_THD_MSB_REG		(CHGR_BASE + 0x67)
#define CHGR_ADC_ITERM_UP_THD_LSB_REG		(CHGR_BASE + 0x68)
#define CHGR_ADC_ITERM_LO_THD_MSB_REG		(CHGR_BASE + 0x69)
#define CHGR_ADC_ITERM_LO_THD_LSB_REG		(CHGR_BASE + 0x6A)

#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)
@@ -102,6 +107,10 @@ enum {
#define JEITA_CCCOMP_CFG_COLD_REG		(CHGR_BASE + 0x93)

#define CHGR_JEITA_THRESHOLD_BASE_REG(i)	(CHGR_BASE + 0x94 + (i * 4))

#define CHGR_ENG_CHARGING_CFG_REG		(CHGR_BASE + 0xC0)
#define CHGR_ITERM_USE_ANALOG_BIT		BIT(3)

/********************************
 *  DCDC Peripheral Registers  *
 ********************************/