Merge "qpnp-fg-gen3: Add support to configure force battery profile loading"
This commit is contained in:
commit
d610af9453
5 changed files with 207 additions and 82 deletions
|
@ -87,7 +87,8 @@ First Level Node - FG Gen3 device
|
|||
Value type: <u32>
|
||||
Definition: Percentage of monotonic SOC increase upon which the delta
|
||||
SOC interrupt will be triggered. If this property is not
|
||||
specified, then the default value will be 1.
|
||||
specified, then the default value will be 1. Possible
|
||||
values are in the range of 0 to 12.
|
||||
|
||||
- qcom,fg-recharge-soc-thr
|
||||
Usage: optional
|
||||
|
@ -145,6 +146,13 @@ First Level Node - FG Gen3 device
|
|||
Value type: <bool>
|
||||
Definition: Enables the cycle counter feature.
|
||||
|
||||
- qcom,fg-force-load-profile
|
||||
Usage: optional
|
||||
Value type: <bool>
|
||||
Definition: If set, battery profile will be force loaded if the profile
|
||||
loaded earlier by bootloader doesn't match with the profile
|
||||
available in the device tree.
|
||||
|
||||
==========================================================
|
||||
Second Level Nodes - Peripherals managed by FG Gen3 driver
|
||||
==========================================================
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
qcom,ascent_3450mah {
|
||||
/* #Ascent_860_82209_0000_3450mAh_averaged_MasterSlave_Jul20th2016*/
|
||||
qcom,max-voltage-uv = <4350000>;
|
||||
qcom,fg-cc-cv-threshold-mv = <4340>;
|
||||
qcom,nom-batt-capacity-mah = <3450>;
|
||||
qcom,batt-id-kohm = <60>;
|
||||
qcom,battery-beta = <3435>;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
qcom,itech_3000mah {
|
||||
/* #Itech_B00826LF_3000mAh_ver1660_averaged_MasterSlave_Jul20th2016*/
|
||||
qcom,max-voltage-uv = <4350000>;
|
||||
qcom,fg-cc-cv-threshold-mv = <4340>;
|
||||
qcom,nom-batt-capacity-mah = <3000>;
|
||||
qcom,batt-id-kohm = <100>;
|
||||
qcom,battery-beta = <3450>;
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
CHARS_PER_ITEM) + 1) \
|
||||
|
||||
#define FG_SRAM_ADDRESS_MAX 255
|
||||
#define PROFILE_LEN 224
|
||||
#define PROFILE_COMP_LEN 148
|
||||
#define BUCKET_COUNT 8
|
||||
#define BUCKET_SOC_PCT (256 / BUCKET_COUNT)
|
||||
|
||||
|
@ -121,6 +123,8 @@ enum fg_sram_param_id {
|
|||
FG_SRAM_CUTOFF_VOLT,
|
||||
FG_SRAM_EMPTY_VOLT,
|
||||
FG_SRAM_VBATT_LOW,
|
||||
FG_SRAM_FLOAT_VOLT,
|
||||
FG_SRAM_VBATT_FULL,
|
||||
FG_SRAM_ESR_TIMER_DISCHG_MAX,
|
||||
FG_SRAM_ESR_TIMER_DISCHG_INIT,
|
||||
FG_SRAM_ESR_TIMER_CHG_MAX,
|
||||
|
@ -177,6 +181,7 @@ struct fg_dt_props {
|
|||
int esr_timer_charging;
|
||||
int esr_timer_awake;
|
||||
int esr_timer_asleep;
|
||||
bool force_load_profile;
|
||||
};
|
||||
|
||||
/* parameters from battery profile */
|
||||
|
@ -184,6 +189,7 @@ struct fg_batt_props {
|
|||
const char *batt_type_str;
|
||||
char *batt_profile;
|
||||
int float_volt_uv;
|
||||
int vbatt_full_mv;
|
||||
int fastchg_curr_ma;
|
||||
int batt_id_kohm;
|
||||
};
|
||||
|
@ -200,8 +206,8 @@ struct fg_cyc_ctr_data {
|
|||
struct fg_irq_info {
|
||||
const char *name;
|
||||
const irq_handler_t handler;
|
||||
int irq;
|
||||
bool wakeable;
|
||||
int irq;
|
||||
};
|
||||
|
||||
struct fg_chip {
|
||||
|
@ -217,7 +223,7 @@ struct fg_chip {
|
|||
struct votable *awake_votable;
|
||||
struct fg_sram_param *sp;
|
||||
int *debug_mask;
|
||||
char *batt_profile;
|
||||
char batt_profile[PROFILE_LEN];
|
||||
struct fg_dt_props dt;
|
||||
struct fg_batt_props bp;
|
||||
struct fg_cyc_ctr_data cyc_ctr;
|
||||
|
@ -227,10 +233,11 @@ struct fg_chip {
|
|||
u32 batt_soc_base;
|
||||
u32 batt_info_base;
|
||||
u32 mem_if_base;
|
||||
int batt_id;
|
||||
int nom_cap_uah;
|
||||
int status;
|
||||
int prev_status;
|
||||
bool batt_id_avail;
|
||||
bool profile_available;
|
||||
bool profile_loaded;
|
||||
bool battery_missing;
|
||||
struct completion soc_update;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#define CUTOFF_VOLT_OFFSET 0
|
||||
#define SYS_TERM_CURR_WORD 6
|
||||
#define SYS_TERM_CURR_OFFSET 0
|
||||
#define VBATT_FULL_WORD 7
|
||||
#define VBATT_FULL_OFFSET 0
|
||||
#define DELTA_SOC_THR_WORD 12
|
||||
#define DELTA_SOC_THR_OFFSET 3
|
||||
#define RECHARGE_SOC_THR_WORD 14
|
||||
|
@ -89,6 +91,8 @@
|
|||
#define EMPTY_VOLT_v2_OFFSET 3
|
||||
#define VBATT_LOW_v2_WORD 16
|
||||
#define VBATT_LOW_v2_OFFSET 0
|
||||
#define FLOAT_VOLT_v2_WORD 16
|
||||
#define FLOAT_VOLT_v2_OFFSET 2
|
||||
|
||||
static int fg_decode_value_16b(struct fg_sram_param *sp,
|
||||
enum fg_sram_param_id id, int val);
|
||||
|
@ -97,9 +101,9 @@ static int fg_decode_default(struct fg_sram_param *sp,
|
|||
static int fg_decode_batt_soc(struct fg_sram_param *sp,
|
||||
enum fg_sram_param_id id, int val);
|
||||
static void fg_encode_voltage(struct fg_sram_param *sp,
|
||||
enum fg_sram_param_id id, int val, u8 *buf);
|
||||
enum fg_sram_param_id id, int val_mv, u8 *buf);
|
||||
static void fg_encode_current(struct fg_sram_param *sp,
|
||||
enum fg_sram_param_id id, int val, u8 *buf);
|
||||
enum fg_sram_param_id id, int val_ma, u8 *buf);
|
||||
static void fg_encode_default(struct fg_sram_param *sp,
|
||||
enum fg_sram_param_id id, int val, u8 *buf);
|
||||
|
||||
|
@ -134,11 +138,13 @@ static struct fg_sram_param pmicobalt_v1_sram_params[] = {
|
|||
-2500, fg_encode_voltage, NULL),
|
||||
PARAM(VBATT_LOW, VBATT_LOW_WORD, VBATT_LOW_OFFSET, 1, 100000, 390625,
|
||||
-2500, fg_encode_voltage, NULL),
|
||||
PARAM(VBATT_FULL, VBATT_FULL_WORD, VBATT_FULL_OFFSET, 2, 1000000,
|
||||
244141, 0, fg_encode_voltage, NULL),
|
||||
PARAM(SYS_TERM_CURR, SYS_TERM_CURR_WORD, SYS_TERM_CURR_OFFSET, 3,
|
||||
1000000, 122070, 0, fg_encode_current, NULL),
|
||||
PARAM(CHG_TERM_CURR, CHG_TERM_CURR_WORD, CHG_TERM_CURR_OFFSET, 1,
|
||||
100000, 390625, 0, fg_encode_current, NULL),
|
||||
PARAM(DELTA_SOC_THR, DELTA_SOC_THR_WORD, DELTA_SOC_THR_OFFSET, 1, 256,
|
||||
PARAM(DELTA_SOC_THR, DELTA_SOC_THR_WORD, DELTA_SOC_THR_OFFSET, 1, 2048,
|
||||
100, 0, fg_encode_default, NULL),
|
||||
PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_WORD, RECHARGE_SOC_THR_OFFSET,
|
||||
1, 256, 100, 0, fg_encode_default, NULL),
|
||||
|
@ -172,12 +178,16 @@ static struct fg_sram_param pmicobalt_v2_sram_params[] = {
|
|||
15625, -2000, fg_encode_voltage, NULL),
|
||||
PARAM(VBATT_LOW, VBATT_LOW_v2_WORD, VBATT_LOW_v2_OFFSET, 1, 1000,
|
||||
15625, -2000, fg_encode_voltage, NULL),
|
||||
PARAM(FLOAT_VOLT, FLOAT_VOLT_v2_WORD, FLOAT_VOLT_v2_OFFSET, 1, 1000,
|
||||
15625, -2000, fg_encode_voltage, NULL),
|
||||
PARAM(VBATT_FULL, VBATT_FULL_WORD, VBATT_FULL_OFFSET, 2, 1000000,
|
||||
244141, 0, fg_encode_voltage, NULL),
|
||||
PARAM(SYS_TERM_CURR, SYS_TERM_CURR_WORD, SYS_TERM_CURR_OFFSET, 3,
|
||||
1000000, 122070, 0, fg_encode_current, NULL),
|
||||
PARAM(CHG_TERM_CURR, CHG_TERM_CURR_v2_WORD, CHG_TERM_CURR_v2_OFFSET, 1,
|
||||
100000, 390625, 0, fg_encode_current, NULL),
|
||||
PARAM(DELTA_SOC_THR, DELTA_SOC_THR_v2_WORD, DELTA_SOC_THR_v2_OFFSET, 1,
|
||||
256, 100, 0, fg_encode_default, NULL),
|
||||
2048, 100, 0, fg_encode_default, NULL),
|
||||
PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_v2_WORD,
|
||||
RECHARGE_SOC_THR_v2_OFFSET, 1, 256, 100, 0, fg_encode_default,
|
||||
NULL),
|
||||
|
@ -264,6 +274,12 @@ module_param_named(
|
|||
sram_update_period_ms, fg_sram_update_period_ms, int, S_IRUSR | S_IWUSR
|
||||
);
|
||||
|
||||
static bool fg_sram_dump;
|
||||
module_param_named(
|
||||
sram_dump, fg_sram_dump, bool, S_IRUSR | S_IWUSR
|
||||
);
|
||||
|
||||
|
||||
/* All getters HERE */
|
||||
|
||||
static int fg_decode_value_16b(struct fg_sram_param *sp,
|
||||
|
@ -302,14 +318,14 @@ static int fg_decode(struct fg_sram_param *sp, enum fg_sram_param_id id,
|
|||
}
|
||||
|
||||
static void fg_encode_voltage(struct fg_sram_param *sp,
|
||||
enum fg_sram_param_id id, int val, u8 *buf)
|
||||
enum fg_sram_param_id id, int val_mv, u8 *buf)
|
||||
{
|
||||
int i, mask = 0xff;
|
||||
int64_t temp;
|
||||
|
||||
val += sp[id].offset;
|
||||
temp = (int64_t)div_u64((u64)val * sp[id].numrtr, sp[id].denmtr);
|
||||
pr_debug("temp: %llx id: %d, val: %d, buf: [ ", temp, id, val);
|
||||
val_mv += sp[id].offset;
|
||||
temp = (int64_t)div_u64((u64)val_mv * sp[id].numrtr, sp[id].denmtr);
|
||||
pr_debug("temp: %llx id: %d, val_mv: %d, buf: [ ", temp, id, val_mv);
|
||||
for (i = 0; i < sp[id].len; i++) {
|
||||
buf[i] = temp & mask;
|
||||
temp >>= 8;
|
||||
|
@ -319,15 +335,15 @@ static void fg_encode_voltage(struct fg_sram_param *sp,
|
|||
}
|
||||
|
||||
static void fg_encode_current(struct fg_sram_param *sp,
|
||||
enum fg_sram_param_id id, int val, u8 *buf)
|
||||
enum fg_sram_param_id id, int val_ma, u8 *buf)
|
||||
{
|
||||
int i, mask = 0xff;
|
||||
int64_t temp;
|
||||
s64 current_ma;
|
||||
|
||||
current_ma = val;
|
||||
current_ma = val_ma;
|
||||
temp = (int64_t)div_s64(current_ma * sp[id].numrtr, sp[id].denmtr);
|
||||
pr_debug("temp: %llx id: %d, val: %d, buf: [ ", temp, id, val);
|
||||
pr_debug("temp: %llx id: %d, val: %d, buf: [ ", temp, id, val_ma);
|
||||
for (i = 0; i < sp[id].len; i++) {
|
||||
buf[i] = temp & mask;
|
||||
temp >>= 8;
|
||||
|
@ -593,14 +609,12 @@ static int fg_get_batt_id(struct fg_chip *chip, int *val)
|
|||
return rc;
|
||||
}
|
||||
|
||||
chip->batt_id_avail = true;
|
||||
fg_dbg(chip, FG_STATUS, "batt_id: %d\n", batt_id);
|
||||
|
||||
*val = batt_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PROFILE_LEN 224
|
||||
static int fg_get_batt_profile(struct fg_chip *chip)
|
||||
{
|
||||
struct device_node *node = chip->dev->of_node;
|
||||
|
@ -614,13 +628,14 @@ static int fg_get_batt_profile(struct fg_chip *chip)
|
|||
return rc;
|
||||
}
|
||||
|
||||
batt_id /= 1000;
|
||||
chip->batt_id = batt_id;
|
||||
batt_node = of_find_node_by_name(node, "qcom,battery-data");
|
||||
if (!batt_node) {
|
||||
pr_err("Batterydata not available\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
batt_id /= 1000;
|
||||
profile_node = of_batterydata_get_best_profile(batt_node, batt_id,
|
||||
NULL);
|
||||
if (IS_ERR(profile_node))
|
||||
|
@ -652,6 +667,13 @@ static int fg_get_batt_profile(struct fg_chip *chip)
|
|||
chip->bp.fastchg_curr_ma = -EINVAL;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32(profile_node, "qcom,fg-cc-cv-threshold-mv",
|
||||
&chip->bp.vbatt_full_mv);
|
||||
if (rc < 0) {
|
||||
pr_err("battery cc_cv threshold unavailable, rc:%d\n", rc);
|
||||
chip->bp.vbatt_full_mv = -EINVAL;
|
||||
}
|
||||
|
||||
data = of_get_property(profile_node, "qcom,fg-profile-data", &len);
|
||||
if (!data) {
|
||||
pr_err("No profile data available\n");
|
||||
|
@ -663,6 +685,7 @@ static int fg_get_batt_profile(struct fg_chip *chip)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
chip->profile_available = true;
|
||||
memcpy(chip->batt_profile, data, len);
|
||||
return 0;
|
||||
}
|
||||
|
@ -912,46 +935,82 @@ static int fg_get_cycle_count(struct fg_chip *chip)
|
|||
return count;
|
||||
}
|
||||
|
||||
#define PROFILE_COMP_LEN 32
|
||||
#define SOC_READY_WAIT_MS 2000
|
||||
static void profile_load_work(struct work_struct *work)
|
||||
static void dump_sram(u8 *buf, int len)
|
||||
{
|
||||
struct fg_chip *chip = container_of(work,
|
||||
struct fg_chip,
|
||||
profile_load_work.work);
|
||||
int rc;
|
||||
u8 buf[PROFILE_COMP_LEN], val;
|
||||
bool tried_again = false, profiles_same = false;
|
||||
int i;
|
||||
char str[16];
|
||||
|
||||
if (!chip->batt_id_avail) {
|
||||
pr_err("batt_id not available\n");
|
||||
return;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_profile_load_required(struct fg_chip *chip)
|
||||
{
|
||||
u8 buf[PROFILE_COMP_LEN], val;
|
||||
bool profiles_same = false;
|
||||
int rc;
|
||||
|
||||
rc = fg_sram_read(chip, PROFILE_INTEGRITY_WORD,
|
||||
PROFILE_INTEGRITY_OFFSET, &val, 1, FG_IMA_DEFAULT);
|
||||
if (rc < 0) {
|
||||
pr_err("failed to read profile integrity rc=%d\n", rc);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
vote(chip->awake_votable, PROFILE_LOAD, true, 0);
|
||||
/* Check if integrity bit is set */
|
||||
if (val == 0x01) {
|
||||
fg_dbg(chip, FG_STATUS, "Battery profile integrity bit is set\n");
|
||||
rc = fg_sram_read(chip, PROFILE_LOAD_WORD, PROFILE_LOAD_OFFSET,
|
||||
buf, PROFILE_COMP_LEN, FG_IMA_DEFAULT);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in reading battery profile, rc:%d\n", rc);
|
||||
goto out;
|
||||
return false;
|
||||
}
|
||||
profiles_same = memcmp(chip->batt_profile, buf,
|
||||
PROFILE_COMP_LEN) == 0;
|
||||
if (profiles_same) {
|
||||
fg_dbg(chip, FG_STATUS, "Battery profile is same\n");
|
||||
fg_dbg(chip, FG_STATUS, "Battery profile is same, not loading it\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
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) {
|
||||
pr_info("FG: loaded profile:\n");
|
||||
dump_sram(buf, PROFILE_COMP_LEN);
|
||||
pr_info("FG: available profile:\n");
|
||||
dump_sram(chip->batt_profile, PROFILE_LEN);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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) {
|
||||
pr_info("FG: profile to be loaded:\n");
|
||||
dump_sram(chip->batt_profile, PROFILE_LEN);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define SOC_READY_WAIT_MS 2000
|
||||
static void profile_load_work(struct work_struct *work)
|
||||
{
|
||||
struct fg_chip *chip = container_of(work,
|
||||
struct fg_chip,
|
||||
profile_load_work.work);
|
||||
bool tried_again = false;
|
||||
u8 buf[2], val;
|
||||
int rc;
|
||||
|
||||
vote(chip->awake_votable, PROFILE_LOAD, true, 0);
|
||||
if (!is_profile_load_required(chip))
|
||||
goto done;
|
||||
}
|
||||
fg_dbg(chip, FG_STATUS, "profiles are different?\n");
|
||||
}
|
||||
|
||||
clear_cycle_counter(chip);
|
||||
fg_dbg(chip, FG_STATUS, "profile loading started\n");
|
||||
|
@ -1182,6 +1241,32 @@ static int fg_hw_init(struct fg_chip *chip)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* This SRAM register is only present in v2.0 */
|
||||
if (chip->pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4 &&
|
||||
chip->bp.float_volt_uv > 0) {
|
||||
fg_encode(chip->sp, FG_SRAM_FLOAT_VOLT,
|
||||
chip->bp.float_volt_uv / 1000, buf);
|
||||
rc = fg_sram_write(chip, chip->sp[FG_SRAM_FLOAT_VOLT].addr_word,
|
||||
chip->sp[FG_SRAM_FLOAT_VOLT].addr_byte, buf,
|
||||
chip->sp[FG_SRAM_FLOAT_VOLT].len, FG_IMA_DEFAULT);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in writing float_volt, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (chip->bp.vbatt_full_mv > 0) {
|
||||
fg_encode(chip->sp, FG_SRAM_VBATT_FULL, chip->bp.vbatt_full_mv,
|
||||
buf);
|
||||
rc = fg_sram_write(chip, chip->sp[FG_SRAM_VBATT_FULL].addr_word,
|
||||
chip->sp[FG_SRAM_VBATT_FULL].addr_byte, buf,
|
||||
chip->sp[FG_SRAM_VBATT_FULL].len, FG_IMA_DEFAULT);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in writing vbatt_full, rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
fg_encode(chip->sp, FG_SRAM_CHG_TERM_CURR, chip->dt.chg_term_curr_ma,
|
||||
buf);
|
||||
rc = fg_sram_write(chip, chip->sp[FG_SRAM_CHG_TERM_CURR].addr_word,
|
||||
|
@ -1311,28 +1396,6 @@ static int fg_memif_init(struct fg_chip *chip)
|
|||
return fg_ima_init(chip);
|
||||
}
|
||||
|
||||
static int fg_batt_profile_init(struct fg_chip *chip)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!chip->batt_profile) {
|
||||
chip->batt_profile = devm_kcalloc(chip->dev, PROFILE_LEN,
|
||||
sizeof(*chip->batt_profile),
|
||||
GFP_KERNEL);
|
||||
if (!chip->batt_profile)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rc = fg_get_batt_profile(chip);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in getting battery profile, rc:%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
schedule_delayed_work(&chip->profile_load_work, msecs_to_jiffies(0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* INTERRUPT HANDLERS STAY HERE */
|
||||
|
||||
static irqreturn_t fg_vbatt_low_irq_handler(int irq, void *data)
|
||||
|
@ -1360,16 +1423,16 @@ static irqreturn_t fg_batt_missing_irq_handler(int irq, void *data)
|
|||
chip->battery_missing = (status & BT_MISS_BIT);
|
||||
|
||||
if (chip->battery_missing) {
|
||||
chip->batt_id_avail = false;
|
||||
chip->profile_available = false;
|
||||
chip->profile_loaded = false;
|
||||
clear_cycle_counter(chip);
|
||||
} else {
|
||||
rc = fg_batt_profile_init(chip);
|
||||
rc = fg_get_batt_profile(chip);
|
||||
if (rc < 0) {
|
||||
pr_err("Error in initializing battery profile, rc=%d\n",
|
||||
rc);
|
||||
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;
|
||||
|
@ -1445,39 +1508,78 @@ static irqreturn_t fg_dummy_irq_handler(int irq, void *data)
|
|||
static struct fg_irq_info fg_irqs[FG_IRQ_MAX] = {
|
||||
/* BATT_SOC irqs */
|
||||
[MSOC_FULL_IRQ] = {
|
||||
"msoc-full", fg_soc_irq_handler, true },
|
||||
.name = "msoc-full",
|
||||
.handler = fg_soc_irq_handler,
|
||||
},
|
||||
[MSOC_HIGH_IRQ] = {
|
||||
"msoc-high", fg_soc_irq_handler, true },
|
||||
.name = "msoc-high",
|
||||
.handler = fg_soc_irq_handler,
|
||||
.wakeable = true,
|
||||
},
|
||||
[MSOC_EMPTY_IRQ] = {
|
||||
"msoc-empty", fg_empty_soc_irq_handler, true },
|
||||
.name = "msoc-empty",
|
||||
.handler = fg_empty_soc_irq_handler,
|
||||
.wakeable = true,
|
||||
},
|
||||
[MSOC_LOW_IRQ] = {
|
||||
"msoc-low", fg_soc_irq_handler },
|
||||
.name = "msoc-low",
|
||||
.handler = fg_soc_irq_handler,
|
||||
.wakeable = true,
|
||||
},
|
||||
[MSOC_DELTA_IRQ] = {
|
||||
"msoc-delta", fg_delta_soc_irq_handler, true },
|
||||
.name = "msoc-delta",
|
||||
.handler = fg_delta_soc_irq_handler,
|
||||
.wakeable = true,
|
||||
},
|
||||
[BSOC_DELTA_IRQ] = {
|
||||
"bsoc-delta", fg_delta_soc_irq_handler, true },
|
||||
.name = "bsoc-delta",
|
||||
.handler = fg_dummy_irq_handler,
|
||||
},
|
||||
[SOC_READY_IRQ] = {
|
||||
"soc-ready", fg_first_est_irq_handler, true },
|
||||
.name = "soc-ready",
|
||||
.handler = fg_first_est_irq_handler,
|
||||
.wakeable = true,
|
||||
},
|
||||
[SOC_UPDATE_IRQ] = {
|
||||
"soc-update", fg_soc_update_irq_handler },
|
||||
.name = "soc-update",
|
||||
.handler = fg_soc_update_irq_handler,
|
||||
},
|
||||
/* BATT_INFO irqs */
|
||||
[BATT_TEMP_DELTA_IRQ] = {
|
||||
"batt-temp-delta", fg_delta_batt_temp_irq_handler },
|
||||
.name = "batt-temp-delta",
|
||||
.handler = fg_delta_batt_temp_irq_handler,
|
||||
},
|
||||
[BATT_MISSING_IRQ] = {
|
||||
"batt-missing", fg_batt_missing_irq_handler, true },
|
||||
.name = "batt-missing",
|
||||
.handler = fg_batt_missing_irq_handler,
|
||||
.wakeable = true,
|
||||
},
|
||||
[ESR_DELTA_IRQ] = {
|
||||
"esr-delta", fg_dummy_irq_handler },
|
||||
.name = "esr-delta",
|
||||
.handler = fg_dummy_irq_handler,
|
||||
},
|
||||
[VBATT_LOW_IRQ] = {
|
||||
"vbatt-low", fg_vbatt_low_irq_handler, true },
|
||||
.name = "vbatt-low",
|
||||
.handler = fg_vbatt_low_irq_handler,
|
||||
.wakeable = true,
|
||||
},
|
||||
[VBATT_PRED_DELTA_IRQ] = {
|
||||
"vbatt-pred-delta", fg_dummy_irq_handler },
|
||||
.name = "vbatt-pred-delta",
|
||||
.handler = fg_dummy_irq_handler,
|
||||
},
|
||||
/* MEM_IF irqs */
|
||||
[DMA_GRANT_IRQ] = {
|
||||
"dma-grant", fg_dummy_irq_handler },
|
||||
.name = "dma-grant",
|
||||
.handler = fg_dummy_irq_handler,
|
||||
},
|
||||
[MEM_XCP_IRQ] = {
|
||||
"mem-xcp", fg_dummy_irq_handler },
|
||||
.name = "mem-xcp",
|
||||
.handler = fg_dummy_irq_handler,
|
||||
},
|
||||
[IMA_RDY_IRQ] = {
|
||||
"ima-rdy", fg_dummy_irq_handler },
|
||||
.name = "ima-rdy",
|
||||
.handler = fg_dummy_irq_handler,
|
||||
},
|
||||
};
|
||||
|
||||
static int fg_get_irq_index_byname(const char *name)
|
||||
|
@ -1638,6 +1740,11 @@ static int fg_parse_dt(struct fg_chip *chip)
|
|||
}
|
||||
}
|
||||
|
||||
rc = fg_get_batt_profile(chip);
|
||||
if (rc < 0)
|
||||
pr_warn("profile for batt_id=%dKOhms not found..using OTP, rc:%d\n",
|
||||
chip->batt_id, rc);
|
||||
|
||||
/* Read all the optional properties below */
|
||||
rc = of_property_read_u32(node, "qcom,fg-cutoff-voltage", &temp);
|
||||
if (rc < 0)
|
||||
|
@ -1724,6 +1831,9 @@ static int fg_parse_dt(struct fg_chip *chip)
|
|||
if (chip->cyc_ctr.en)
|
||||
chip->cyc_ctr.id = 1;
|
||||
|
||||
chip->dt.force_load_profile = of_property_read_bool(node,
|
||||
"qcom,fg-force-load-profile");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1836,10 +1946,8 @@ static int fg_gen3_probe(struct platform_device *pdev)
|
|||
goto exit;
|
||||
}
|
||||
|
||||
rc = fg_batt_profile_init(chip);
|
||||
if (rc < 0)
|
||||
dev_warn(chip->dev, "Error in initializing battery profile, rc:%d\n",
|
||||
rc);
|
||||
if (chip->profile_available)
|
||||
schedule_delayed_work(&chip->profile_load_work, 0);
|
||||
|
||||
device_init_wakeup(chip->dev, true);
|
||||
pr_debug("FG GEN3 driver successfully probed\n");
|
||||
|
|
Loading…
Add table
Reference in a new issue