qpnp-fg-gen3: add support for configuring ESR filter coefficients

As per the hardware documentation, add support for configuring
ESR tight and broad filters for normal and low temperature. This
is needed as the low temperature ESR filter coefficients are not
functional in the hardware.

All the filter values (in terms of percentage) can be configured
through the device tree. When the battery temperature goes below
10 C or user configured temperature threshold, ESR filter values
of room temperature will be applied to ESR low temperature
filters. Once the battery temperature goes above 10 C, original
values will be applied back to ESR low temperature filters.

Change-Id: I347f194f96ace3036a3c49efe0306d9f909cef36
Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
This commit is contained in:
Subbaraman Narayanamurthy 2016-12-22 15:10:09 -08:00
parent 1a53645674
commit 15c1d49794
3 changed files with 187 additions and 1 deletions

View file

@ -273,6 +273,45 @@ First Level Node - FG Gen3 device
is specified, then ESR to Rslow scaling factors will be
updated to account it for an accurate ESR.
- qcom,fg-esr-filter-switch-temp
Usage: optional
Value type: <u32>
Definition: Battery temperature threshold below which low temperature
ESR filter coefficients will be switched to normal
temperature ESR filter coefficients. If this is not
specified, then the default value used will be 100. Unit is
in decidegC.
- qcom,fg-esr-tight-filter-micro-pct
Usage: optional
Value type: <u32>
Definition: Value in micro percentage for ESR tight filter. If this is
not specified, then a default value of 3907 (0.39 %) will
be used. Lowest possible value is 1954 (0.19 %).
- qcom,fg-esr-broad-filter-micro-pct
Usage: optional
Value type: <u32>
Definition: Value in micro percentage for ESR broad filter. If this is
not specified, then a default value of 99610 (9.96 %) will
be used. Lowest possible value is 1954 (0.19 %).
- qcom,fg-esr-tight-lt-filter-micro-pct
Usage: optional
Value type: <u32>
Definition: Value in micro percentage for low temperature ESR tight
filter. If this is not specified, then a default value of
48829 (4.88 %) will be used. Lowest possible value is 1954
(0.19 %).
- qcom,fg-esr-broad-lt-filter-micro-pct
Usage: optional
Value type: <u32>
Definition: Value in micro percentage for low temperature ESR broad
filter. If this is not specified, then a default value of
148438 (14.84 %) will be used. Lowest possible value is
1954 (0.19 %).
==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================

View file

@ -161,6 +161,8 @@ enum fg_sram_param_id {
FG_SRAM_RECHARGE_VBATT_THR,
FG_SRAM_KI_COEFF_MED_DISCHG,
FG_SRAM_KI_COEFF_HI_DISCHG,
FG_SRAM_ESR_TIGHT_FILTER,
FG_SRAM_ESR_BROAD_FILTER,
FG_SRAM_MAX,
};
@ -225,6 +227,11 @@ struct fg_dt_props {
int cl_min_cap_limit;
int jeita_hyst_temp;
int batt_temp_delta;
int esr_flt_switch_temp;
int esr_tight_flt_upct;
int esr_broad_flt_upct;
int esr_tight_lt_flt_upct;
int esr_broad_lt_flt_upct;
int jeita_thresholds[NUM_JEITA_LEVELS];
int ki_coeff_soc[KI_COEFF_SOC_LEVELS];
int ki_coeff_med_dischg[KI_COEFF_SOC_LEVELS];
@ -337,6 +344,7 @@ struct fg_chip {
bool ki_coeff_dischg_en;
bool esr_fcc_ctrl_en;
bool soc_reporting_ready;
bool esr_flt_cold_temp_en;
struct completion soc_update;
struct completion soc_ready;
struct delayed_work profile_load_work;

View file

@ -37,6 +37,11 @@
#define SYS_TERM_CURR_OFFSET 0
#define VBATT_FULL_WORD 7
#define VBATT_FULL_OFFSET 0
#define ESR_FILTER_WORD 8
#define ESR_UPD_TIGHT_OFFSET 0
#define ESR_UPD_BROAD_OFFSET 1
#define ESR_UPD_TIGHT_LOW_TEMP_OFFSET 2
#define ESR_UPD_BROAD_LOW_TEMP_OFFSET 3
#define KI_COEFF_MED_DISCHG_WORD 9
#define KI_COEFF_MED_DISCHG_OFFSET 3
#define KI_COEFF_HI_DISCHG_WORD 10
@ -203,6 +208,10 @@ static struct fg_sram_param pmi8998_v1_sram_params[] = {
PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_WORD,
KI_COEFF_HI_DISCHG_OFFSET, 1, 1000, 244141, 0,
fg_encode_default, NULL),
PARAM(ESR_TIGHT_FILTER, ESR_FILTER_WORD, ESR_UPD_TIGHT_OFFSET,
1, 512, 1000000, 0, fg_encode_default, NULL),
PARAM(ESR_BROAD_FILTER, ESR_FILTER_WORD, ESR_UPD_BROAD_OFFSET,
1, 512, 1000000, 0, fg_encode_default, NULL),
};
static struct fg_sram_param pmi8998_v2_sram_params[] = {
@ -263,6 +272,10 @@ static struct fg_sram_param pmi8998_v2_sram_params[] = {
PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_v2_WORD,
KI_COEFF_HI_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
fg_encode_default, NULL),
PARAM(ESR_TIGHT_FILTER, ESR_FILTER_WORD, ESR_UPD_TIGHT_OFFSET,
1, 512, 1000000, 0, fg_encode_default, NULL),
PARAM(ESR_BROAD_FILTER, ESR_FILTER_WORD, ESR_UPD_BROAD_OFFSET,
1, 512, 1000000, 0, fg_encode_default, NULL),
};
static struct fg_alg_flag pmi8998_v1_alg_flags[] = {
@ -1550,6 +1563,65 @@ static int fg_adjust_recharge_soc(struct fg_chip *chip)
return 0;
}
static int fg_esr_filter_config(struct fg_chip *chip, int batt_temp)
{
u8 esr_tight_lt_flt, esr_broad_lt_flt;
bool cold_temp = false;
int rc;
/*
* If the battery temperature is lower than -20 C, then skip modifying
* ESR filter.
*/
if (batt_temp < -210)
return 0;
/*
* If battery temperature is lesser than 10 C (default), then apply the
* normal ESR tight and broad filter values to ESR low temperature tight
* and broad filters. If battery temperature is higher than 10 C, then
* apply back the low temperature ESR filter coefficients to ESR low
* temperature tight and broad filters.
*/
if (batt_temp > chip->dt.esr_flt_switch_temp
&& chip->esr_flt_cold_temp_en) {
fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
chip->dt.esr_tight_lt_flt_upct, &esr_tight_lt_flt);
fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
chip->dt.esr_broad_lt_flt_upct, &esr_broad_lt_flt);
} else if (batt_temp <= chip->dt.esr_flt_switch_temp
&& !chip->esr_flt_cold_temp_en) {
fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
chip->dt.esr_tight_flt_upct, &esr_tight_lt_flt);
fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
chip->dt.esr_broad_flt_upct, &esr_broad_lt_flt);
cold_temp = true;
} else {
return 0;
}
rc = fg_sram_write(chip, ESR_FILTER_WORD,
ESR_UPD_TIGHT_LOW_TEMP_OFFSET, &esr_tight_lt_flt, 1,
FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing ESR LT tight filter, rc=%d\n", rc);
return rc;
}
rc = fg_sram_write(chip, ESR_FILTER_WORD,
ESR_UPD_BROAD_LOW_TEMP_OFFSET, &esr_broad_lt_flt, 1,
FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing ESR LT broad filter, rc=%d\n", rc);
return rc;
}
chip->esr_flt_cold_temp_en = cold_temp;
fg_dbg(chip, FG_STATUS, "applied %s ESR filter values\n",
cold_temp ? "cold" : "normal");
return 0;
}
static int fg_esr_fcc_config(struct fg_chip *chip)
{
union power_supply_propval prop = {0, };
@ -2790,6 +2862,26 @@ static int fg_hw_init(struct fg_chip *chip)
}
}
fg_encode(chip->sp, FG_SRAM_ESR_TIGHT_FILTER,
chip->dt.esr_tight_flt_upct, buf);
rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_word,
chip->sp[FG_SRAM_ESR_TIGHT_FILTER].addr_byte, buf,
chip->sp[FG_SRAM_ESR_TIGHT_FILTER].len, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing ESR tight filter, rc=%d\n", rc);
return rc;
}
fg_encode(chip->sp, FG_SRAM_ESR_BROAD_FILTER,
chip->dt.esr_broad_flt_upct, buf);
rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_word,
chip->sp[FG_SRAM_ESR_BROAD_FILTER].addr_byte, buf,
chip->sp[FG_SRAM_ESR_BROAD_FILTER].len, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing ESR broad filter, rc=%d\n", rc);
return rc;
}
return 0;
}
@ -2901,6 +2993,10 @@ static irqreturn_t fg_delta_batt_temp_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
rc = fg_esr_filter_config(chip, batt_temp);
if (rc < 0)
pr_err("Error in configuring ESR filter rc:%d\n", rc);
if (!is_charger_available(chip)) {
chip->last_batt_temp = batt_temp;
return IRQ_HANDLED;
@ -3207,6 +3303,11 @@ static int fg_parse_ki_coefficients(struct fg_chip *chip)
#define DEFAULT_CL_MAX_LIM_DECIPERC 0
#define BTEMP_DELTA_LOW 2
#define BTEMP_DELTA_HIGH 10
#define DEFAULT_ESR_FLT_TEMP_DECIDEGC 100
#define DEFAULT_ESR_TIGHT_FLT_UPCT 3907
#define DEFAULT_ESR_BROAD_FLT_UPCT 99610
#define DEFAULT_ESR_TIGHT_LT_FLT_UPCT 48829
#define DEFAULT_ESR_BROAD_LT_FLT_UPCT 148438
static int fg_parse_dt(struct fg_chip *chip)
{
struct device_node *child, *revid_node, *node = chip->dev->of_node;
@ -3483,6 +3584,40 @@ static int fg_parse_dt(struct fg_chip *chip)
else
chip->dt.rconn_mohms = temp;
rc = of_property_read_u32(node, "qcom,fg-esr-filter-switch-temp",
&temp);
if (rc < 0)
chip->dt.esr_flt_switch_temp = DEFAULT_ESR_FLT_TEMP_DECIDEGC;
else
chip->dt.esr_flt_switch_temp = temp;
rc = of_property_read_u32(node, "qcom,fg-esr-tight-filter-micro-pct",
&temp);
if (rc < 0)
chip->dt.esr_tight_flt_upct = DEFAULT_ESR_TIGHT_FLT_UPCT;
else
chip->dt.esr_tight_flt_upct = temp;
rc = of_property_read_u32(node, "qcom,fg-esr-broad-filter-micro-pct",
&temp);
if (rc < 0)
chip->dt.esr_broad_flt_upct = DEFAULT_ESR_BROAD_FLT_UPCT;
else
chip->dt.esr_broad_flt_upct = temp;
rc = of_property_read_u32(node, "qcom,fg-esr-tight-lt-filter-micro-pct",
&temp);
if (rc < 0)
chip->dt.esr_tight_lt_flt_upct = DEFAULT_ESR_TIGHT_LT_FLT_UPCT;
else
chip->dt.esr_tight_lt_flt_upct = temp;
rc = of_property_read_u32(node, "qcom,fg-esr-broad-lt-filter-micro-pct",
&temp);
if (rc < 0)
chip->dt.esr_broad_lt_flt_upct = DEFAULT_ESR_BROAD_LT_FLT_UPCT;
else
chip->dt.esr_broad_lt_flt_upct = temp;
return 0;
}
@ -3608,9 +3743,13 @@ static int fg_gen3_probe(struct platform_device *pdev)
if (!rc)
rc = fg_get_battery_temp(chip, &batt_temp);
if (!rc)
if (!rc) {
pr_info("battery SOC:%d voltage: %duV temp: %d id: %dKOhms\n",
msoc, volt_uv, batt_temp, chip->batt_id_ohms / 1000);
rc = fg_esr_filter_config(chip, batt_temp);
if (rc < 0)
pr_err("Error in configuring ESR filter rc:%d\n", rc);
}
device_init_wakeup(chip->dev, true);
if (chip->profile_available)