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

Commit de79845d 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-smbcharger: fix software esr pulse algorithm"

parents 00f7e35a 24e83f4b
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ enum pmic_subtype {
enum wa_flags {
	IADC_GAIN_COMP_WA = BIT(0),
	USE_CC_SOC_REG = BIT(1),
	PULSE_REQUEST_WA = BIT(2)
};

enum current_sense_type {
@@ -410,7 +411,7 @@ struct fg_chip {
	struct power_supply	bms_psy;
	struct mutex		rw_lock;
	struct mutex		sysfs_restart_lock;
	struct work_struct	batt_profile_init;
	struct delayed_work	batt_profile_init;
	struct work_struct	dump_sram;
	struct work_struct	status_change_work;
	struct work_struct	cycle_count_work;
@@ -3242,7 +3243,7 @@ static void status_change_work(struct work_struct *work)
			enable_irq_wake(chip->batt_irq[VBATT_LOW].irq);
			chip->vbat_low_irq_enabled = true;
		}
		if (capacity == 100)
		if (!!(chip->wa_flag & PULSE_REQUEST_WA) && capacity == 100)
			fg_configure_soc(chip);
	} else if (chip->status == POWER_SUPPLY_STATUS_DISCHARGING) {
		if (chip->vbat_low_irq_enabled) {
@@ -3764,7 +3765,7 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *_chip)
		if (!chip->use_otp_profile) {
			reinit_completion(&chip->batt_id_avail);
			reinit_completion(&chip->first_soc_done);
			schedule_work(&chip->batt_profile_init);
			schedule_delayed_work(&chip->batt_profile_init, 0);
			cancel_delayed_work(&chip->update_sram_data);
			schedule_delayed_work(
				&chip->update_sram_data,
@@ -4426,6 +4427,7 @@ fail:
#define PROFILE_COMPARE_LEN		32
#define THERMAL_COEFF_ADDR		0x444
#define THERMAL_COEFF_OFFSET		0x2
#define BATTERY_PSY_WAIT_MS		2000
static int fg_batt_profile_init(struct fg_chip *chip)
{
	int rc = 0, ret;
@@ -4593,6 +4595,14 @@ wait:
				DUMP_PREFIX_NONE, 16, 1,
				chip->batt_profile, len, false);
	}
	if (!chip->batt_psy && chip->batt_psy_name)
		chip->batt_psy = power_supply_get_by_name(chip->batt_psy_name);

	if (!chip->batt_psy) {
		if (fg_debug_mask & FG_STATUS)
			pr_info("batt psy not registered\n");
		goto reschedule;
	}
	if (chip->power_supply_registered)
		power_supply_changed(&chip->bms_psy);

@@ -4660,6 +4670,12 @@ no_profile:
		power_supply_changed(&chip->bms_psy);
	fg_relax(&chip->profile_wakeup_source);
	return rc;
reschedule:
	schedule_delayed_work(
		&chip->batt_profile_init,
		msecs_to_jiffies(BATTERY_PSY_WAIT_MS));
	fg_relax(&chip->profile_wakeup_source);
	return 0;
}

static void check_empty_work(struct work_struct *work)
@@ -4682,7 +4698,7 @@ static void batt_profile_init(struct work_struct *work)
{
	struct fg_chip *chip = container_of(work,
				struct fg_chip,
				batt_profile_init);
				batt_profile_init.work);

	if (fg_batt_profile_init(chip))
		pr_err("failed to initialize profile\n");
@@ -5205,11 +5221,11 @@ static void fg_cleanup(struct fg_chip *chip)
	cancel_delayed_work_sync(&chip->update_temp_work);
	cancel_delayed_work_sync(&chip->update_jeita_setting);
	cancel_delayed_work_sync(&chip->check_empty_work);
	cancel_delayed_work_sync(&chip->batt_profile_init);
	alarm_try_to_cancel(&chip->fg_cap_learning_alarm);
	cancel_work_sync(&chip->rslow_comp_work);
	cancel_work_sync(&chip->set_resume_soc_work);
	cancel_work_sync(&chip->fg_cap_learning_work);
	cancel_work_sync(&chip->batt_profile_init);
	cancel_work_sync(&chip->dump_sram);
	cancel_work_sync(&chip->status_change_work);
	cancel_work_sync(&chip->cycle_count_work);
@@ -5875,6 +5891,7 @@ static int fg_hw_init(struct fg_chip *chip)
	switch (chip->pmic_subtype) {
	case PMI8994:
		rc = fg_8994_hw_init(chip);
		chip->wa_flag |= PULSE_REQUEST_WA;
		break;
	case PMI8996:
	case PMI8950:
@@ -6017,7 +6034,7 @@ static void delayed_init_work(struct work_struct *work)
		update_temp_data(&chip->update_temp_work.work);

	if (!chip->use_otp_profile)
		schedule_work(&chip->batt_profile_init);
		schedule_delayed_work(&chip->batt_profile_init, 0);

	if (chip->wa_flag & IADC_GAIN_COMP_WA) {
		/* read default gain config */
@@ -6130,9 +6147,9 @@ static int fg_probe(struct spmi_device *spmi)
	INIT_DELAYED_WORK(&chip->update_sram_data, update_sram_data_work);
	INIT_DELAYED_WORK(&chip->update_temp_work, update_temp_data);
	INIT_DELAYED_WORK(&chip->check_empty_work, check_empty_work);
	INIT_DELAYED_WORK(&chip->batt_profile_init, batt_profile_init);
	INIT_WORK(&chip->rslow_comp_work, rslow_comp_work);
	INIT_WORK(&chip->fg_cap_learning_work, fg_cap_learning_work);
	INIT_WORK(&chip->batt_profile_init, batt_profile_init);
	INIT_WORK(&chip->dump_sram, dump_sram);
	INIT_WORK(&chip->status_change_work, status_change_work);
	INIT_WORK(&chip->cycle_count_work, update_cycle_count);
@@ -6293,10 +6310,10 @@ cancel_work:
	cancel_delayed_work_sync(&chip->update_sram_data);
	cancel_delayed_work_sync(&chip->update_temp_work);
	cancel_delayed_work_sync(&chip->check_empty_work);
	cancel_delayed_work_sync(&chip->batt_profile_init);
	alarm_try_to_cancel(&chip->fg_cap_learning_alarm);
	cancel_work_sync(&chip->set_resume_soc_work);
	cancel_work_sync(&chip->fg_cap_learning_work);
	cancel_work_sync(&chip->batt_profile_init);
	cancel_work_sync(&chip->dump_sram);
	cancel_work_sync(&chip->status_change_work);
	cancel_work_sync(&chip->cycle_count_work);
+79 −40
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ struct smbchg_chip {
	int				prechg_safety_time;
	int				bmd_pin_src;
	int				jeita_temp_hard_limit;
	int				sw_esr_pulse_current_ma;
	bool				use_vfloat_adjustments;
	bool				iterm_disabled;
	bool				bmd_algo_disabled;
@@ -178,7 +179,6 @@ struct smbchg_chip {
	int				otg_retries;
	ktime_t				otg_enable_time;
	bool				aicl_deglitch_short;
	bool				sw_esr_pulse_en;
	bool				safety_timer_en;
	bool				aicl_complete;
	bool				usb_ov_det;
@@ -283,6 +283,7 @@ enum smbchg_wa {
	SMBCHG_HVDCP_9V_EN_WA	= BIT(1),
	SMBCHG_USB100_WA = BIT(2),
	SMBCHG_BATT_OV_WA = BIT(3),
	SMBCHG_CC_ESR_WA = BIT(4),
};

enum print_reason {
@@ -1836,6 +1837,12 @@ static int smbchg_set_fastchg_current_raw(struct smbchg_chip *chip,
		return rc;
	}

	if (chip->tables.usb_ilim_ma_table[i] == chip->fastchg_current_ma) {
		pr_smb(PR_STATUS, "skipping fastchg current request: %d\n",
				chip->fastchg_current_ma);
		return 0;
	}

	cur_val = i & FCC_MASK;
	rc = smbchg_sec_masked_write(chip, chip->chgr_base + FCC_CFG,
				FCC_MASK, cur_val);
@@ -1856,17 +1863,10 @@ static int smbchg_set_fastchg_current(struct smbchg_chip *chip,
{
	int rc = 0;

	if (chip->sw_esr_pulse_current_ma > 0)
		current_ma = chip->sw_esr_pulse_current_ma;
	mutex_lock(&chip->fcc_lock);
	if (chip->sw_esr_pulse_en)
		current_ma -= ESR_PULSE_CURRENT_DELTA_MA;
	/* If the requested FCC is same, do not configure it again */
	if (current_ma == chip->fastchg_current_ma) {
		pr_smb(PR_STATUS, "not configuring FCC current: %d FCC: %d\n",
			current_ma, chip->fastchg_current_ma);
		goto out;
	}
	rc = smbchg_set_fastchg_current_raw(chip, current_ma);
out:
	mutex_unlock(&chip->fcc_lock);
	return rc;
}
@@ -1887,8 +1887,20 @@ static int smbchg_parallel_usb_charging_en(struct smbchg_chip *chip, bool en)
static int smbchg_sw_esr_pulse_en(struct smbchg_chip *chip, bool en)
{
	int rc;
	int ibat_ua;

	chip->sw_esr_pulse_en = en;
	rc = get_property_from_fg(chip,
			POWER_SUPPLY_PROP_CURRENT_NOW, &ibat_ua);
	if (rc) {
		pr_smb(PR_STATUS,
			"bms psy does not support current_now rc = %d\n", rc);
		return rc;
	}
	chip->sw_esr_pulse_current_ma = max((ibat_ua / 1000)
			- ESR_PULSE_CURRENT_DELTA_MA,
			chip->iterm_ma + ESR_PULSE_CURRENT_DELTA_MA);
	pr_smb(PR_STATUS, "setting sw esr pulse fcc = %d\n",
			chip->sw_esr_pulse_current_ma);
	rc = smbchg_set_fastchg_current(chip, chip->target_fastchg_current_ma);
	if (rc)
		return rc;
@@ -2726,6 +2738,33 @@ static int smbchg_fastchg_current_comp_set(struct smbchg_chip *chip,
	return rc;
}

#define CFG_TCC_REG			0xF9
#define CHG_ITERM_MASK			SMB_MASK(2, 0)
static int smbchg_iterm_set(struct smbchg_chip *chip, int iterm_ma)
{
	int rc;
	u8 reg;

	reg = find_closest_in_array(
			chip->tables.iterm_ma_table,
			chip->tables.iterm_ma_len,
			iterm_ma);

	rc = smbchg_sec_masked_write(chip,
			chip->chgr_base + CFG_TCC_REG,
			CHG_ITERM_MASK, reg);
	if (rc) {
		dev_err(chip->dev,
			"Couldn't set iterm rc = %d\n", rc);
		return rc;
	}
	pr_smb(PR_STATUS, "set tcc (%d) to 0x%02x\n",
			iterm_ma, reg);
	chip->iterm_ma = iterm_ma;

	return 0;
}

#define FV_CMP_CFG	0xF5
#define FV_COMP_MASK	SMB_MASK(5, 0)
static int smbchg_float_voltage_comp_set(struct smbchg_chip *chip, int code)
@@ -2933,8 +2972,7 @@ static void smbchg_cc_esr_wa_check(struct smbchg_chip *chip)
{
	int rc, esr_count;

	/* WA is not required on SCHG_LITE */
	if (chip->schg_version == QPNP_SCHG_LITE)
	if (!(chip->wa_flags & SMBCHG_CC_ESR_WA))
		return;

	if (!is_usb_present(chip) && !is_dc_present(chip)) {
@@ -3166,7 +3204,7 @@ static void smbchg_aicl_deglitch_wa_check(struct smbchg_chip *chip)
#define LOADING_BATT_TYPE	"Loading Battery Data"
static int smbchg_config_chg_battery_type(struct smbchg_chip *chip)
{
	int rc = 0, max_voltage_uv = 0, fastchg_ma = 0, ret = 0;
	int rc = 0, max_voltage_uv = 0, fastchg_ma = 0, ret = 0, iterm_ua = 0;
	struct device_node *batt_node, *profile_node;
	struct device_node *node = chip->spmi->dev.of_node;
	union power_supply_propval prop = {0,};
@@ -3221,6 +3259,29 @@ static int smbchg_config_chg_battery_type(struct smbchg_chip *chip)
		}
	}

	/* change chg term */
	rc = of_property_read_u32(profile_node, "qcom,chg-term-ua",
						&iterm_ua);
	if (rc && rc != -EINVAL) {
		pr_warn("couldn't read battery term current=%d\n", rc);
		ret = rc;
	} else if (!rc) {
		if (chip->iterm_ma != (iterm_ua / 1000)
				&& !chip->iterm_disabled) {
			pr_info("Term current changed from %dmA to %dmA for battery-type %s\n",
				chip->iterm_ma, (iterm_ua / 1000),
				chip->battery_type);
			rc = smbchg_iterm_set(chip,
						(iterm_ua / 1000));
			if (rc < 0) {
				dev_err(chip->dev,
				"Couldn't set iterm rc = %d\n", rc);
				return rc;
			}
		}
		chip->iterm_ma = iterm_ua / 1000;
	}

	/*
	 * Only configure from profile if fastchg-ma is not defined in the
	 * charger device node.
@@ -6030,16 +6091,6 @@ static inline int get_bpd(const char *name)
#define I_TERM_BIT			BIT(3)
#define AUTO_RECHG_BIT			BIT(2)
#define CHARGER_INHIBIT_BIT		BIT(0)
#define CFG_TCC_REG			0xF9
#define CHG_ITERM_50MA			0x1
#define CHG_ITERM_100MA			0x2
#define CHG_ITERM_150MA			0x3
#define CHG_ITERM_200MA			0x4
#define CHG_ITERM_250MA			0x5
#define CHG_ITERM_300MA			0x0
#define CHG_ITERM_500MA			0x6
#define CHG_ITERM_600MA			0x7
#define CHG_ITERM_MASK			SMB_MASK(2, 0)
#define USB51_COMMAND_POL		BIT(2)
#define USB51AC_CTRL			BIT(1)
#define TR_8OR32B			0xFE
@@ -6270,21 +6321,7 @@ static int smbchg_hw_init(struct smbchg_chip *chip)
			dev_err(chip->dev, "Error: Both iterm_disabled and iterm_ma set\n");
			return -EINVAL;
		} else {
			reg = find_closest_in_array(
					chip->tables.iterm_ma_table,
					chip->tables.iterm_ma_len,
					chip->iterm_ma);

			rc = smbchg_sec_masked_write(chip,
					chip->chgr_base + CFG_TCC_REG,
					CHG_ITERM_MASK, reg);
			if (rc) {
				dev_err(chip->dev,
					"Couldn't set iterm rc = %d\n", rc);
				return rc;
			}
			pr_smb(PR_STATUS, "set tcc (%d) to 0x%02x\n",
					chip->iterm_ma, reg);
			smbchg_iterm_set(chip, chip->iterm_ma);
		}
	}

@@ -7142,7 +7179,8 @@ static int smbchg_check_chg_version(struct smbchg_chip *chip)
	switch (pmic_rev_id->pmic_subtype) {
	case PMI8994:
		chip->wa_flags |= SMBCHG_AICL_DEGLITCH_WA
				| SMBCHG_BATT_OV_WA;
				| SMBCHG_BATT_OV_WA
				| SMBCHG_CC_ESR_WA;
		use_pmi8994_tables(chip);
		chip->schg_version = QPNP_SCHG;
		break;
@@ -7158,6 +7196,7 @@ static int smbchg_check_chg_version(struct smbchg_chip *chip)
		chip->schg_version = QPNP_SCHG_LITE;
		break;
	case PMI8996:
		chip->wa_flags |= SMBCHG_CC_ESR_WA;
		use_pmi8996_tables(chip);
		chip->schg_version = QPNP_SCHG;
		break;