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:
parent
1a53645674
commit
15c1d49794
3 changed files with 187 additions and 1 deletions
|
@ -273,6 +273,45 @@ First Level Node - FG Gen3 device
|
||||||
is specified, then ESR to Rslow scaling factors will be
|
is specified, then ESR to Rslow scaling factors will be
|
||||||
updated to account it for an accurate ESR.
|
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
|
Second Level Nodes - Peripherals managed by FG Gen3 driver
|
||||||
==========================================================
|
==========================================================
|
||||||
|
|
|
@ -161,6 +161,8 @@ enum fg_sram_param_id {
|
||||||
FG_SRAM_RECHARGE_VBATT_THR,
|
FG_SRAM_RECHARGE_VBATT_THR,
|
||||||
FG_SRAM_KI_COEFF_MED_DISCHG,
|
FG_SRAM_KI_COEFF_MED_DISCHG,
|
||||||
FG_SRAM_KI_COEFF_HI_DISCHG,
|
FG_SRAM_KI_COEFF_HI_DISCHG,
|
||||||
|
FG_SRAM_ESR_TIGHT_FILTER,
|
||||||
|
FG_SRAM_ESR_BROAD_FILTER,
|
||||||
FG_SRAM_MAX,
|
FG_SRAM_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -225,6 +227,11 @@ struct fg_dt_props {
|
||||||
int cl_min_cap_limit;
|
int cl_min_cap_limit;
|
||||||
int jeita_hyst_temp;
|
int jeita_hyst_temp;
|
||||||
int batt_temp_delta;
|
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 jeita_thresholds[NUM_JEITA_LEVELS];
|
||||||
int ki_coeff_soc[KI_COEFF_SOC_LEVELS];
|
int ki_coeff_soc[KI_COEFF_SOC_LEVELS];
|
||||||
int ki_coeff_med_dischg[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 ki_coeff_dischg_en;
|
||||||
bool esr_fcc_ctrl_en;
|
bool esr_fcc_ctrl_en;
|
||||||
bool soc_reporting_ready;
|
bool soc_reporting_ready;
|
||||||
|
bool esr_flt_cold_temp_en;
|
||||||
struct completion soc_update;
|
struct completion soc_update;
|
||||||
struct completion soc_ready;
|
struct completion soc_ready;
|
||||||
struct delayed_work profile_load_work;
|
struct delayed_work profile_load_work;
|
||||||
|
|
|
@ -37,6 +37,11 @@
|
||||||
#define SYS_TERM_CURR_OFFSET 0
|
#define SYS_TERM_CURR_OFFSET 0
|
||||||
#define VBATT_FULL_WORD 7
|
#define VBATT_FULL_WORD 7
|
||||||
#define VBATT_FULL_OFFSET 0
|
#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_WORD 9
|
||||||
#define KI_COEFF_MED_DISCHG_OFFSET 3
|
#define KI_COEFF_MED_DISCHG_OFFSET 3
|
||||||
#define KI_COEFF_HI_DISCHG_WORD 10
|
#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,
|
PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_WORD,
|
||||||
KI_COEFF_HI_DISCHG_OFFSET, 1, 1000, 244141, 0,
|
KI_COEFF_HI_DISCHG_OFFSET, 1, 1000, 244141, 0,
|
||||||
fg_encode_default, NULL),
|
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[] = {
|
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,
|
PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_v2_WORD,
|
||||||
KI_COEFF_HI_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
|
KI_COEFF_HI_DISCHG_v2_OFFSET, 1, 1000, 244141, 0,
|
||||||
fg_encode_default, NULL),
|
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[] = {
|
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;
|
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)
|
static int fg_esr_fcc_config(struct fg_chip *chip)
|
||||||
{
|
{
|
||||||
union power_supply_propval prop = {0, };
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2901,6 +2993,10 @@ static irqreturn_t fg_delta_batt_temp_irq_handler(int irq, void *data)
|
||||||
return IRQ_HANDLED;
|
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)) {
|
if (!is_charger_available(chip)) {
|
||||||
chip->last_batt_temp = batt_temp;
|
chip->last_batt_temp = batt_temp;
|
||||||
return IRQ_HANDLED;
|
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 DEFAULT_CL_MAX_LIM_DECIPERC 0
|
||||||
#define BTEMP_DELTA_LOW 2
|
#define BTEMP_DELTA_LOW 2
|
||||||
#define BTEMP_DELTA_HIGH 10
|
#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)
|
static int fg_parse_dt(struct fg_chip *chip)
|
||||||
{
|
{
|
||||||
struct device_node *child, *revid_node, *node = chip->dev->of_node;
|
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
|
else
|
||||||
chip->dt.rconn_mohms = temp;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3608,9 +3743,13 @@ static int fg_gen3_probe(struct platform_device *pdev)
|
||||||
if (!rc)
|
if (!rc)
|
||||||
rc = fg_get_battery_temp(chip, &batt_temp);
|
rc = fg_get_battery_temp(chip, &batt_temp);
|
||||||
|
|
||||||
if (!rc)
|
if (!rc) {
|
||||||
pr_info("battery SOC:%d voltage: %duV temp: %d id: %dKOhms\n",
|
pr_info("battery SOC:%d voltage: %duV temp: %d id: %dKOhms\n",
|
||||||
msoc, volt_uv, batt_temp, chip->batt_id_ohms / 1000);
|
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);
|
device_init_wakeup(chip->dev, true);
|
||||||
if (chip->profile_available)
|
if (chip->profile_available)
|
||||||
|
|
Loading…
Add table
Reference in a new issue