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

Commit 67d21e89 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-fg-gen3: Add WA for oscillator drift on PM660" into msm-4.9

parents 18337bfe ddabeee9
Loading
Loading
Loading
Loading
+20 −5
Original line number Diff line number Diff line
@@ -128,11 +128,6 @@ enum fg_irq_index {
	FG_IRQ_MAX,
};

/* WA flags */
enum {
	DELTA_SOC_IRQ_WA = BIT(0),
};

/*
 * List of FG_SRAM parameters. Please add a parameter only if it is an entry
 * that will be used either to configure an entity (e.g. termination current)
@@ -152,6 +147,7 @@ enum fg_sram_param_id {
	FG_SRAM_CC_SOC,
	FG_SRAM_CC_SOC_SW,
	FG_SRAM_ACT_BATT_CAP,
	FG_SRAM_TIMEBASE,
	/* Entries below here are configurable during initialization */
	FG_SRAM_CUTOFF_VOLT,
	FG_SRAM_EMPTY_VOLT,
@@ -212,6 +208,7 @@ struct fg_alg_flag {

enum wa_flags {
	PMI8998_V1_REV_WA = BIT(0),
	PM660_TSMC_OSC_WA = BIT(1),
};

enum slope_limit_status {
@@ -325,6 +322,23 @@ static const struct fg_pt fg_ln_table[] = {
	{ 128000,	4852 },
};

/* each tuple is - <temperature in degC, Timebase> */
static const struct fg_pt fg_tsmc_osc_table[] = {
	{ -20,		395064 },
	{ -10,		398114 },
	{   0,		401669 },
	{  10,		404641 },
	{  20,		408856 },
	{  25,		412449 },
	{  30,		416532 },
	{  40,		420289 },
	{  50,		425020 },
	{  60,		430160 },
	{  70,		434175 },
	{  80,		439475 },
	{  90,		444992 },
};

struct fg_chip {
	struct device		*dev;
	struct pmic_revid_data	*pmic_rev_id;
@@ -336,6 +350,7 @@ struct fg_chip {
	struct power_supply	*dc_psy;
	struct power_supply	*parallel_psy;
	struct iio_channel	*batt_id_chan;
	struct iio_channel	*die_temp_chan;
	struct fg_memif		*sram;
	struct fg_irq_info	*irqs;
	struct votable		*awake_votable;
+62 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@
#define ESR_UPD_TIGHT_LOW_TEMP_OFFSET	2
#define ESR_UPD_BROAD_LOW_TEMP_OFFSET	3
#define KI_COEFF_MED_DISCHG_WORD	9
#define TIMEBASE_OFFSET			1
#define KI_COEFF_MED_DISCHG_OFFSET	3
#define KI_COEFF_HI_DISCHG_WORD		10
#define KI_COEFF_HI_DISCHG_OFFSET	0
@@ -261,6 +262,8 @@ static struct fg_sram_param pmi8998_v2_sram_params[] = {
		fg_decode_cc_soc),
	PARAM(ACT_BATT_CAP, ACT_BATT_CAP_BKUP_WORD, ACT_BATT_CAP_BKUP_OFFSET, 2,
		1, 1, 0, NULL, fg_decode_default),
	PARAM(TIMEBASE, KI_COEFF_MED_DISCHG_WORD, TIMEBASE_OFFSET, 2, 1000,
		61000, 0, fg_encode_default, NULL),
	/* Entries below here are configurable during initialization */
	PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000,
		244141, 0, fg_encode_voltage, NULL),
@@ -3365,6 +3368,40 @@ static int fg_memif_init(struct fg_chip *chip)
	return fg_ima_init(chip);
}

static int fg_adjust_timebase(struct fg_chip *chip)
{
	int rc = 0, die_temp;
	s32 time_base = 0;
	u8 buf[2] = {0};

	if ((chip->wa_flags & PM660_TSMC_OSC_WA) && chip->die_temp_chan) {
		rc = iio_read_channel_processed(chip->die_temp_chan, &die_temp);
		if (rc < 0) {
			pr_err("Error in reading die_temp, rc:%d\n", rc);
			return rc;
		}

		rc = fg_lerp(fg_tsmc_osc_table, ARRAY_SIZE(fg_tsmc_osc_table),
					die_temp / 1000, &time_base);
		if (rc < 0) {
			pr_err("Error to lookup fg_tsmc_osc_table rc=%d\n", rc);
			return rc;
		}

		fg_encode(chip->sp, FG_SRAM_TIMEBASE, time_base, buf);
		rc = fg_sram_write(chip,
			chip->sp[FG_SRAM_TIMEBASE].addr_word,
			chip->sp[FG_SRAM_TIMEBASE].addr_byte, buf,
			chip->sp[FG_SRAM_TIMEBASE].len, FG_IMA_DEFAULT);
		if (rc < 0) {
			pr_err("Error in writing timebase, rc=%d\n", rc);
			return rc;
		}
	}

	return 0;
}

/* INTERRUPT HANDLERS STAY HERE */

static irqreturn_t fg_mem_xcp_irq_handler(int irq, void *data)
@@ -3486,6 +3523,10 @@ static irqreturn_t fg_delta_batt_temp_irq_handler(int irq, void *data)
	chip->health = prop.intval;

	if (chip->last_batt_temp != batt_temp) {
		rc = fg_adjust_timebase(chip);
		if (rc < 0)
			pr_err("Error in adjusting timebase, rc=%d\n", rc);

		chip->last_batt_temp = batt_temp;
		power_supply_changed(chip->batt_psy);
	}
@@ -3555,6 +3596,10 @@ static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data)
	if (rc < 0)
		pr_err("Error in validating ESR, rc=%d\n", rc);

	rc = fg_adjust_timebase(chip);
	if (rc < 0)
		pr_err("Error in adjusting timebase, rc=%d\n", rc);

	if (batt_psy_initialized(chip))
		power_supply_changed(chip->batt_psy);

@@ -3897,6 +3942,8 @@ static int fg_parse_dt(struct fg_chip *chip)
		chip->sp = pmi8998_v2_sram_params;
		chip->alg_flags = pmi8998_v2_alg_flags;
		chip->use_ima_single_mode = true;
		if (chip->pmic_rev_id->fab_id == PM660_FAB_ID_TSMC)
			chip->wa_flags |= PM660_TSMC_OSC_WA;
		break;
	default:
		return -EINVAL;
@@ -4238,6 +4285,21 @@ static int fg_gen3_probe(struct platform_device *pdev)
		return rc;
	}

	rc = of_property_match_string(chip->dev->of_node,
				"io-channel-names", "rradc_die_temp");
	if (rc >= 0) {
		chip->die_temp_chan = iio_channel_get(chip->dev,
						"rradc_die_temp");
		if (IS_ERR(chip->die_temp_chan)) {
			if (PTR_ERR(chip->die_temp_chan) != -EPROBE_DEFER)
				pr_err("rradc_die_temp unavailable %ld\n",
					PTR_ERR(chip->die_temp_chan));
			rc = PTR_ERR(chip->die_temp_chan);
			chip->die_temp_chan = NULL;
			return rc;
		}
	}

	chip->awake_votable = create_votable("FG_WS", VOTE_SET_ANY, fg_awake_cb,
					chip);
	if (IS_ERR(chip->awake_votable)) {