Merge "qpnp-fg-gen3: add support for configuring ESR filter coefficients"
This commit is contained in:
commit
0aac3e19af
4 changed files with 346 additions and 39 deletions
|
@ -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
|
||||
==========================================================
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -62,6 +62,7 @@
|
|||
CHARS_PER_ITEM) + 1) \
|
||||
|
||||
#define FG_SRAM_ADDRESS_MAX 255
|
||||
#define FG_SRAM_LEN 504
|
||||
#define PROFILE_LEN 224
|
||||
#define PROFILE_COMP_LEN 148
|
||||
#define BUCKET_COUNT 8
|
||||
|
@ -160,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,
|
||||
};
|
||||
|
||||
|
@ -224,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];
|
||||
|
@ -336,12 +344,14 @@ 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;
|
||||
struct work_struct status_change_work;
|
||||
struct work_struct cycle_count_work;
|
||||
struct delayed_work batt_avg_work;
|
||||
struct delayed_work sram_dump_work;
|
||||
struct fg_circ_buf ibatt_circ_buf;
|
||||
struct fg_circ_buf vbatt_circ_buf;
|
||||
};
|
||||
|
@ -392,6 +402,7 @@ extern int fg_clear_ima_errors_if_any(struct fg_chip *chip, bool check_hw_sts);
|
|||
extern int fg_clear_dma_errors_if_any(struct fg_chip *chip);
|
||||
extern int fg_debugfs_create(struct fg_chip *chip);
|
||||
extern void fill_string(char *str, size_t str_len, u8 *buf, int buf_len);
|
||||
extern void dump_sram(u8 *buf, int addr, int len);
|
||||
extern int64_t twos_compliment_extend(int64_t val, int s_bit_pos);
|
||||
extern s64 fg_float_decode(u16 val);
|
||||
extern bool is_input_present(struct fg_chip *chip);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -10,8 +10,6 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "FG: %s: " fmt, __func__
|
||||
|
||||
#include "fg-core.h"
|
||||
|
||||
void fg_circ_buf_add(struct fg_circ_buf *buf, int val)
|
||||
|
@ -174,6 +172,24 @@ void fill_string(char *str, size_t str_len, u8 *buf, int buf_len)
|
|||
}
|
||||
}
|
||||
|
||||
void dump_sram(u8 *buf, int addr, int len)
|
||||
{
|
||||
int i;
|
||||
char str[16];
|
||||
|
||||
/*
|
||||
* Length passed should be in multiple of 4 as each FG SRAM word
|
||||
* holds 4 bytes. To keep this simple, even if a length which is
|
||||
* not a multiple of 4 bytes or less than 4 bytes is passed, SRAM
|
||||
* registers dumped will be always in multiple of 4 bytes.
|
||||
*/
|
||||
for (i = 0; i < len; i += 4) {
|
||||
str[0] = '\0';
|
||||
fill_string(str, sizeof(str), buf + i, 4);
|
||||
pr_info("%03d %s\n", addr + (i / 4), str);
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool fg_sram_address_valid(u16 address, int len)
|
||||
{
|
||||
if (address > FG_SRAM_ADDRESS_MAX)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -12,6 +12,7 @@
|
|||
|
||||
#define pr_fmt(fmt) "FG: %s: " fmt, __func__
|
||||
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
@ -36,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
|
||||
|
@ -202,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[] = {
|
||||
|
@ -262,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[] = {
|
||||
|
@ -330,17 +344,18 @@ module_param_named(
|
|||
debug_mask, fg_gen3_debug_mask, int, S_IRUSR | S_IWUSR
|
||||
);
|
||||
|
||||
static int fg_sram_update_period_ms = 30000;
|
||||
static bool fg_profile_dump;
|
||||
module_param_named(
|
||||
sram_update_period_ms, fg_sram_update_period_ms, int, S_IRUSR | S_IWUSR
|
||||
profile_dump, fg_profile_dump, bool, S_IRUSR | S_IWUSR
|
||||
);
|
||||
|
||||
static bool fg_sram_dump;
|
||||
static int fg_sram_dump_period_ms = 20000;
|
||||
module_param_named(
|
||||
sram_dump, fg_sram_dump, bool, S_IRUSR | S_IWUSR
|
||||
sram_dump_period_ms, fg_sram_dump_period_ms, int, S_IRUSR | S_IWUSR
|
||||
);
|
||||
|
||||
static int fg_restart;
|
||||
static bool fg_sram_dump;
|
||||
|
||||
/* All getters HERE */
|
||||
|
||||
|
@ -797,7 +812,7 @@ static const char *fg_get_battery_type(struct fg_chip *chip)
|
|||
if (chip->bp.batt_type_str) {
|
||||
if (chip->profile_loaded)
|
||||
return chip->bp.batt_type_str;
|
||||
else
|
||||
else if (chip->profile_available)
|
||||
return LOADING_BATT_TYPE;
|
||||
}
|
||||
|
||||
|
@ -1548,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, };
|
||||
|
@ -1615,6 +1689,18 @@ static int fg_esr_fcc_config(struct fg_chip *chip)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int fg_batt_missing_config(struct fg_chip *chip, bool enable)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = fg_masked_write(chip, BATT_INFO_BATT_MISS_CFG(chip),
|
||||
BM_FROM_BATT_ID_BIT, enable ? BM_FROM_BATT_ID_BIT : 0);
|
||||
if (rc < 0)
|
||||
pr_err("Error in writing to %04x, rc=%d\n",
|
||||
BATT_INFO_BATT_MISS_CFG(chip), rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void fg_batt_avg_update(struct fg_chip *chip)
|
||||
{
|
||||
if (chip->charge_status == chip->prev_charge_status)
|
||||
|
@ -1838,18 +1924,6 @@ static int fg_get_cycle_count(struct fg_chip *chip)
|
|||
return count;
|
||||
}
|
||||
|
||||
static void dump_sram(u8 *buf, int len)
|
||||
{
|
||||
int i;
|
||||
char str[16];
|
||||
|
||||
for (i = 0; i < len; i += 4) {
|
||||
str[0] = '\0';
|
||||
fill_string(str, sizeof(str), buf + i, 4);
|
||||
pr_info("%03d %s\n", PROFILE_LOAD_WORD + (i / 4), str);
|
||||
}
|
||||
}
|
||||
|
||||
#define PROFILE_LOAD_BIT BIT(0)
|
||||
#define BOOTLOADER_LOAD_BIT BIT(1)
|
||||
#define BOOTLOADER_RESTART_BIT BIT(2)
|
||||
|
@ -1885,11 +1959,13 @@ static bool is_profile_load_required(struct fg_chip *chip)
|
|||
|
||||
if (!chip->dt.force_load_profile) {
|
||||
pr_warn("Profiles doesn't match, skipping loading it since force_load_profile is disabled\n");
|
||||
if (fg_sram_dump) {
|
||||
if (fg_profile_dump) {
|
||||
pr_info("FG: loaded profile:\n");
|
||||
dump_sram(buf, PROFILE_COMP_LEN);
|
||||
dump_sram(buf, PROFILE_LOAD_WORD,
|
||||
PROFILE_COMP_LEN);
|
||||
pr_info("FG: available profile:\n");
|
||||
dump_sram(chip->batt_profile, PROFILE_LEN);
|
||||
dump_sram(chip->batt_profile, PROFILE_LOAD_WORD,
|
||||
PROFILE_LEN);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1897,14 +1973,26 @@ static bool is_profile_load_required(struct fg_chip *chip)
|
|||
fg_dbg(chip, FG_STATUS, "Profiles are different, loading the correct one\n");
|
||||
} else {
|
||||
fg_dbg(chip, FG_STATUS, "Profile integrity bit is not set\n");
|
||||
if (fg_sram_dump) {
|
||||
if (fg_profile_dump) {
|
||||
pr_info("FG: profile to be loaded:\n");
|
||||
dump_sram(chip->batt_profile, PROFILE_LEN);
|
||||
dump_sram(chip->batt_profile, PROFILE_LOAD_WORD,
|
||||
PROFILE_LEN);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void clear_battery_profile(struct fg_chip *chip)
|
||||
{
|
||||
u8 val = 0;
|
||||
int rc;
|
||||
|
||||
rc = fg_sram_write(chip, PROFILE_INTEGRITY_WORD,
|
||||
PROFILE_INTEGRITY_OFFSET, &val, 1, FG_IMA_DEFAULT);
|
||||
if (rc < 0)
|
||||
pr_err("failed to write profile integrity rc=%d\n", rc);
|
||||
}
|
||||
|
||||
#define SOC_READY_WAIT_MS 2000
|
||||
static int __fg_restart(struct fg_chip *chip)
|
||||
{
|
||||
|
@ -2056,6 +2144,71 @@ out:
|
|||
vote(chip->awake_votable, PROFILE_LOAD, false, 0);
|
||||
}
|
||||
|
||||
static void sram_dump_work(struct work_struct *work)
|
||||
{
|
||||
struct fg_chip *chip = container_of(work, struct fg_chip,
|
||||
sram_dump_work.work);
|
||||
u8 buf[FG_SRAM_LEN];
|
||||
int rc;
|
||||
s64 timestamp_ms;
|
||||
|
||||
rc = fg_sram_read(chip, 0, 0, buf, FG_SRAM_LEN, FG_IMA_DEFAULT);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in reading FG SRAM, rc:%d\n", rc);
|
||||
goto resched;
|
||||
}
|
||||
|
||||
timestamp_ms = ktime_to_ms(ktime_get_boottime());
|
||||
fg_dbg(chip, FG_STATUS, "SRAM Dump Started at %lld.%lld\n",
|
||||
timestamp_ms / 1000, timestamp_ms % 1000);
|
||||
dump_sram(buf, 0, FG_SRAM_LEN);
|
||||
timestamp_ms = ktime_to_ms(ktime_get_boottime());
|
||||
fg_dbg(chip, FG_STATUS, "SRAM Dump done at %lld.%lld\n",
|
||||
timestamp_ms / 1000, timestamp_ms % 1000);
|
||||
resched:
|
||||
schedule_delayed_work(&chip->sram_dump_work,
|
||||
msecs_to_jiffies(fg_sram_dump_period_ms));
|
||||
}
|
||||
|
||||
static int fg_sram_dump_sysfs(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
int rc;
|
||||
struct power_supply *bms_psy;
|
||||
struct fg_chip *chip;
|
||||
bool old_val = fg_sram_dump;
|
||||
|
||||
rc = param_set_bool(val, kp);
|
||||
if (rc) {
|
||||
pr_err("Unable to set fg_sram_dump: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (fg_sram_dump == old_val)
|
||||
return 0;
|
||||
|
||||
bms_psy = power_supply_get_by_name("bms");
|
||||
if (!bms_psy) {
|
||||
pr_err("bms psy not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
chip = power_supply_get_drvdata(bms_psy);
|
||||
if (fg_sram_dump)
|
||||
schedule_delayed_work(&chip->sram_dump_work,
|
||||
msecs_to_jiffies(fg_sram_dump_period_ms));
|
||||
else
|
||||
cancel_delayed_work_sync(&chip->sram_dump_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct kernel_param_ops fg_sram_dump_ops = {
|
||||
.set = fg_sram_dump_sysfs,
|
||||
.get = param_get_bool,
|
||||
};
|
||||
|
||||
module_param_cb(sram_dump_en, &fg_sram_dump_ops, &fg_sram_dump, 0644);
|
||||
|
||||
static int fg_restart_sysfs(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
int rc;
|
||||
|
@ -2355,7 +2508,7 @@ static int fg_psy_get_property(struct power_supply *psy,
|
|||
pval->intval = chip->cl.nom_cap_uah;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_RESISTANCE_ID:
|
||||
rc = fg_get_batt_id(chip, &pval->intval);
|
||||
pval->intval = chip->batt_id_ohms;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_BATTERY_TYPE:
|
||||
pval->strval = fg_get_battery_type(chip);
|
||||
|
@ -2709,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;
|
||||
}
|
||||
|
||||
|
@ -2764,7 +2937,6 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *data)
|
|||
u8 status;
|
||||
int rc;
|
||||
|
||||
fg_dbg(chip, FG_IRQ, "irq %d triggered\n", irq);
|
||||
rc = fg_read(chip, BATT_INFO_INT_RT_STS(chip), &status, 1);
|
||||
if (rc < 0) {
|
||||
pr_err("failed to read addr=0x%04x, rc=%d\n",
|
||||
|
@ -2772,23 +2944,39 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *data)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
fg_dbg(chip, FG_IRQ, "irq %d triggered sts:%d\n", irq, status);
|
||||
chip->battery_missing = (status & BT_MISS_BIT);
|
||||
|
||||
if (chip->battery_missing) {
|
||||
chip->profile_available = false;
|
||||
chip->profile_loaded = false;
|
||||
clear_cycle_counter(chip);
|
||||
chip->soc_reporting_ready = false;
|
||||
} else {
|
||||
rc = fg_get_batt_profile(chip);
|
||||
if (rc < 0) {
|
||||
chip->soc_reporting_ready = true;
|
||||
pr_err("Error in getting battery profile, rc:%d\n", rc);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
schedule_delayed_work(&chip->profile_load_work, 0);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
rc = fg_batt_missing_config(chip, false);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in disabling BMD, rc=%d\n", rc);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
rc = fg_get_batt_profile(chip);
|
||||
if (rc < 0) {
|
||||
chip->soc_reporting_ready = true;
|
||||
pr_err("Error in getting battery profile, rc:%d\n", rc);
|
||||
goto enable_bmd;
|
||||
}
|
||||
|
||||
clear_battery_profile(chip);
|
||||
schedule_delayed_work(&chip->profile_load_work, 0);
|
||||
|
||||
enable_bmd:
|
||||
/* Wait for 200ms before enabling BMD again */
|
||||
msleep(200);
|
||||
rc = fg_batt_missing_config(chip, true);
|
||||
if (rc < 0)
|
||||
pr_err("Error in enabling BMD, rc=%d\n", rc);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
@ -2805,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;
|
||||
|
@ -3111,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;
|
||||
|
@ -3387,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;
|
||||
}
|
||||
|
||||
|
@ -3449,6 +3680,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
|
|||
INIT_WORK(&chip->status_change_work, status_change_work);
|
||||
INIT_WORK(&chip->cycle_count_work, cycle_count_work);
|
||||
INIT_DELAYED_WORK(&chip->batt_avg_work, batt_avg_work);
|
||||
INIT_DELAYED_WORK(&chip->sram_dump_work, sram_dump_work);
|
||||
|
||||
rc = fg_memif_init(chip);
|
||||
if (rc < 0) {
|
||||
|
@ -3511,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)
|
||||
|
@ -3542,6 +3778,8 @@ static int fg_gen3_suspend(struct device *dev)
|
|||
}
|
||||
|
||||
cancel_delayed_work_sync(&chip->batt_avg_work);
|
||||
if (fg_sram_dump)
|
||||
cancel_delayed_work_sync(&chip->sram_dump_work);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3563,6 +3801,9 @@ static int fg_gen3_resume(struct device *dev)
|
|||
fg_circ_buf_clr(&chip->ibatt_circ_buf);
|
||||
fg_circ_buf_clr(&chip->vbatt_circ_buf);
|
||||
schedule_delayed_work(&chip->batt_avg_work, 0);
|
||||
if (fg_sram_dump)
|
||||
schedule_delayed_work(&chip->sram_dump_work,
|
||||
msecs_to_jiffies(fg_sram_dump_period_ms));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue