Loading Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen4.txt +10 −2 Original line number Diff line number Diff line Loading @@ -72,8 +72,9 @@ First Level Node - FG Gen4 device Value type: <u32> Definition: Percentage of SOC increase upon which the delta monotonic & battery SOC interrupts will be triggered. If this property is not specified, then the default value will be 1. Possible values are in the range of 0 to 12. is not specified, then the default value will be 5 (0.5 %). Unit is in deci-percentage. Possible values are in the range of 1 to 124. - qcom,fg-esr-timer-chg-fast Usage: optional Loading Loading @@ -189,6 +190,13 @@ First Level Node - FG Gen4 device Definition: Battery temperature hysteresis threshold. Possible values are: 0, 1, 2 and 3. Unit is in Kelvin or Celsius. - qcom,fg-batt-therm-freq Usage: optional Value type: <u32> Definition: Battery thermistor interval in seconds. Possible values are from 1-255. If not specified, then the default value configured is 8. - qcom,fg-force-load-profile Usage: optional Value type: <empty> Loading drivers/power/supply/qcom/qpnp-fg-gen4.c +92 −38 Original line number Diff line number Diff line Loading @@ -170,6 +170,8 @@ #define CC_SOC_v2_OFFSET 0 #define MONOTONIC_SOC_v2_WORD 469 #define MONOTONIC_SOC_v2_OFFSET 0 #define FIRST_LOG_CURRENT_v2_WORD 471 #define FIRST_LOG_CURRENT_v2_OFFSET 0 static struct fg_irq_info fg_irqs[FG_GEN4_IRQ_MAX]; Loading Loading @@ -237,6 +239,7 @@ struct fg_gen4_chip { int esr_actual; int esr_nominal; int soh; int esr_soh_cycle_count; bool first_profile_load; bool ki_coeff_dischg_en; bool slope_limit_en; Loading @@ -245,6 +248,7 @@ struct fg_gen4_chip { bool esr_fast_cal_timer_expired; bool esr_fast_calib_retry; bool esr_fcc_ctrl_en; bool esr_soh_notified; bool rslow_low; bool rapid_soc_dec_en; bool vbatt_low; Loading Loading @@ -345,9 +349,9 @@ static struct fg_sram_param pm8150b_v1_sram_params[] = { PARAM(SYS_TERM_CURR, SYS_TERM_CURR_WORD, SYS_TERM_CURR_OFFSET, 2, 100000, 48828, 0, fg_encode_current, NULL), PARAM(DELTA_MSOC_THR, DELTA_MSOC_THR_WORD, DELTA_MSOC_THR_OFFSET, 1, 2048, 100, 0, fg_encode_default, NULL), 1, 2048, 1000, 0, fg_encode_default, NULL), PARAM(DELTA_BSOC_THR, DELTA_BSOC_THR_WORD, DELTA_BSOC_THR_OFFSET, 1, 2048, 100, 0, fg_encode_default, NULL), 1, 2048, 1000, 0, fg_encode_default, NULL), PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD, ESR_TIMER_DISCHG_MAX_OFFSET, 1, 1, 1, 0, fg_encode_default, NULL), Loading Loading @@ -437,9 +441,9 @@ static struct fg_sram_param pm8150b_v2_sram_params[] = { PARAM(SYS_TERM_CURR, SYS_TERM_CURR_WORD, SYS_TERM_CURR_OFFSET, 2, 100000, 48828, 0, fg_encode_current, NULL), PARAM(DELTA_MSOC_THR, DELTA_MSOC_THR_WORD, DELTA_MSOC_THR_OFFSET, 1, 2048, 100, 0, fg_encode_default, NULL), 1, 2048, 1000, 0, fg_encode_default, NULL), PARAM(DELTA_BSOC_THR, DELTA_BSOC_THR_WORD, DELTA_BSOC_THR_OFFSET, 1, 2048, 100, 0, fg_encode_default, NULL), 1, 2048, 1000, 0, fg_encode_default, NULL), PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD, ESR_TIMER_DISCHG_MAX_OFFSET, 1, 1, 1, 0, fg_encode_default, NULL), Loading Loading @@ -1759,7 +1763,7 @@ static void profile_load_work(struct work_struct *work) struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); int64_t nom_cap_uah; u8 val, buf[2]; u8 val, mask, buf[2]; int rc; vote(fg->awake_votable, PROFILE_LOAD, true, 0); Loading Loading @@ -1802,6 +1806,24 @@ static void profile_load_work(struct work_struct *work) goto out; } /* Enable side loading for voltage and current */ val = mask = BIT(0); rc = fg_sram_masked_write(fg, SYS_CONFIG_WORD, SYS_CONFIG_OFFSET, mask, val, FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in setting SYS_CONFIG_WORD[0], rc=%d\n", rc); goto out; } /* Clear first logged main current ADC values */ buf[0] = buf[1] = 0; rc = fg_sram_write(fg, FIRST_LOG_CURRENT_v2_WORD, FIRST_LOG_CURRENT_v2_OFFSET, buf, 2, FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in clearing FIRST_LOG_CURRENT rc=%d\n", rc); goto out; } /* Set the profile integrity bit */ val = HLOS_RESTART_BIT | PROFILE_LOAD_BIT; rc = fg_sram_write(fg, PROFILE_INTEGRITY_WORD, Loading @@ -1817,6 +1839,16 @@ static void profile_load_work(struct work_struct *work) goto out; } /* Clear side loading for voltage and current */ val = 0; mask = BIT(0); rc = fg_sram_masked_write(fg, SYS_CONFIG_WORD, SYS_CONFIG_OFFSET, mask, val, FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in clearing SYS_CONFIG_WORD[0], rc=%d\n", rc); goto out; } fg_dbg(fg, FG_STATUS, "SOC is ready\n"); fg->profile_load_status = PROFILE_LOADED; Loading Loading @@ -1938,7 +1970,7 @@ static void get_batt_psy_props(struct fg_dev *fg) static int fg_gen4_esr_soh_update(struct fg_dev *fg) { struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); int rc, msoc, esr_uohms; int rc, msoc, esr_uohms, tmp; if (!fg->soc_reporting_ready || fg->battery_missing) { chip->esr_actual = -EINVAL; Loading @@ -1946,14 +1978,28 @@ static int fg_gen4_esr_soh_update(struct fg_dev *fg) return 0; } if (fg->charge_status == POWER_SUPPLY_STATUS_CHARGING) { rc = get_cycle_count(chip->counter, &tmp); if (rc < 0) pr_err("Couldn't get cycle count rc=%d\n", rc); else if (tmp != chip->esr_soh_cycle_count) chip->esr_soh_notified = false; if (fg->charge_status != POWER_SUPPLY_STATUS_CHARGING || chip->esr_soh_notified) return 0; rc = fg_get_msoc(fg, &msoc); if (rc < 0) { pr_err("Error in getting msoc, rc=%d\n", rc); return rc; } if (msoc == ESR_SOH_SOC) { if (msoc != ESR_SOH_SOC) { fg_dbg(fg, FG_STATUS, "msoc: %d, not publishing ESR params\n", msoc); return 0; } rc = fg_get_sram_prop(fg, FG_SRAM_ESR_ACT, &esr_uohms); if (rc < 0) { pr_err("Error in getting esr_actual, rc=%d\n", Loading @@ -1976,8 +2022,12 @@ static int fg_gen4_esr_soh_update(struct fg_dev *fg) if (fg->batt_psy) power_supply_changed(fg->batt_psy); } } rc = get_cycle_count(chip->counter, &chip->esr_soh_cycle_count); if (rc < 0) pr_err("Couldn't get cycle count rc=%d\n", rc); chip->esr_soh_notified = true; return 0; } Loading Loading @@ -2720,10 +2770,13 @@ static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data) { struct fg_dev *fg = data; struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); int rc, batt_soc, batt_temp; int rc, batt_soc, batt_temp, msoc_raw; bool input_present = is_input_present(fg); fg_dbg(fg, FG_IRQ, "irq %d triggered\n", irq); rc = fg_get_msoc_raw(fg, &msoc_raw); if (!rc) fg_dbg(fg, FG_IRQ, "irq %d triggered msoc_raw: %d\n", irq, msoc_raw); get_batt_psy_props(fg); Loading Loading @@ -3072,6 +3125,7 @@ static void pl_current_en_work(struct work_struct *work) return; vote(chip->parallel_current_en_votable, FG_PARALLEL_EN_VOTER, en, 0); vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, false, 0); } static void pl_enable_work(struct work_struct *work) Loading Loading @@ -3734,7 +3788,6 @@ static int fg_parallel_current_en_cb(struct votable *votable, void *data, fg_dbg(fg, FG_STATUS, "Parallel current summing: %d\n", enable); vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, false, 0); return rc; } Loading Loading @@ -3933,7 +3986,7 @@ static int fg_gen4_hw_init(struct fg_gen4_chip *chip) } } if (chip->dt.delta_soc_thr > 0 && chip->dt.delta_soc_thr < 100) { if (chip->dt.delta_soc_thr > 0 && chip->dt.delta_soc_thr < 125) { fg_encode(fg->sp, FG_SRAM_DELTA_MSOC_THR, chip->dt.delta_soc_thr, buf); rc = fg_sram_write(fg, Loading Loading @@ -4404,7 +4457,7 @@ static void fg_gen4_parse_batt_temp_dt(struct fg_gen4_chip *chip) #define DEFAULT_EMPTY_VOLT_MV 2812 #define DEFAULT_SYS_TERM_CURR_MA -125 #define DEFAULT_CUTOFF_CURR_MA 200 #define DEFAULT_DELTA_SOC_THR 1 #define DEFAULT_DELTA_SOC_THR 5 /* 0.5 % */ #define DEFAULT_CL_START_SOC 15 #define DEFAULT_CL_MIN_TEMP_DECIDEGC 150 #define DEFAULT_CL_MAX_TEMP_DECIDEGC 500 Loading Loading @@ -4714,6 +4767,7 @@ static int fg_gen4_probe(struct platform_device *pdev) fg->batt_id_ohms = -EINVAL; chip->ki_coeff_full_soc[0] = -EINVAL; chip->ki_coeff_full_soc[1] = -EINVAL; chip->esr_soh_cycle_count = -EINVAL; fg->regmap = dev_get_regmap(fg->dev->parent, NULL); if (!fg->regmap) { dev_err(fg->dev, "Parent regmap is unavailable\n"); Loading Loading
Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen4.txt +10 −2 Original line number Diff line number Diff line Loading @@ -72,8 +72,9 @@ First Level Node - FG Gen4 device Value type: <u32> Definition: Percentage of SOC increase upon which the delta monotonic & battery SOC interrupts will be triggered. If this property is not specified, then the default value will be 1. Possible values are in the range of 0 to 12. is not specified, then the default value will be 5 (0.5 %). Unit is in deci-percentage. Possible values are in the range of 1 to 124. - qcom,fg-esr-timer-chg-fast Usage: optional Loading Loading @@ -189,6 +190,13 @@ First Level Node - FG Gen4 device Definition: Battery temperature hysteresis threshold. Possible values are: 0, 1, 2 and 3. Unit is in Kelvin or Celsius. - qcom,fg-batt-therm-freq Usage: optional Value type: <u32> Definition: Battery thermistor interval in seconds. Possible values are from 1-255. If not specified, then the default value configured is 8. - qcom,fg-force-load-profile Usage: optional Value type: <empty> Loading
drivers/power/supply/qcom/qpnp-fg-gen4.c +92 −38 Original line number Diff line number Diff line Loading @@ -170,6 +170,8 @@ #define CC_SOC_v2_OFFSET 0 #define MONOTONIC_SOC_v2_WORD 469 #define MONOTONIC_SOC_v2_OFFSET 0 #define FIRST_LOG_CURRENT_v2_WORD 471 #define FIRST_LOG_CURRENT_v2_OFFSET 0 static struct fg_irq_info fg_irqs[FG_GEN4_IRQ_MAX]; Loading Loading @@ -237,6 +239,7 @@ struct fg_gen4_chip { int esr_actual; int esr_nominal; int soh; int esr_soh_cycle_count; bool first_profile_load; bool ki_coeff_dischg_en; bool slope_limit_en; Loading @@ -245,6 +248,7 @@ struct fg_gen4_chip { bool esr_fast_cal_timer_expired; bool esr_fast_calib_retry; bool esr_fcc_ctrl_en; bool esr_soh_notified; bool rslow_low; bool rapid_soc_dec_en; bool vbatt_low; Loading Loading @@ -345,9 +349,9 @@ static struct fg_sram_param pm8150b_v1_sram_params[] = { PARAM(SYS_TERM_CURR, SYS_TERM_CURR_WORD, SYS_TERM_CURR_OFFSET, 2, 100000, 48828, 0, fg_encode_current, NULL), PARAM(DELTA_MSOC_THR, DELTA_MSOC_THR_WORD, DELTA_MSOC_THR_OFFSET, 1, 2048, 100, 0, fg_encode_default, NULL), 1, 2048, 1000, 0, fg_encode_default, NULL), PARAM(DELTA_BSOC_THR, DELTA_BSOC_THR_WORD, DELTA_BSOC_THR_OFFSET, 1, 2048, 100, 0, fg_encode_default, NULL), 1, 2048, 1000, 0, fg_encode_default, NULL), PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD, ESR_TIMER_DISCHG_MAX_OFFSET, 1, 1, 1, 0, fg_encode_default, NULL), Loading Loading @@ -437,9 +441,9 @@ static struct fg_sram_param pm8150b_v2_sram_params[] = { PARAM(SYS_TERM_CURR, SYS_TERM_CURR_WORD, SYS_TERM_CURR_OFFSET, 2, 100000, 48828, 0, fg_encode_current, NULL), PARAM(DELTA_MSOC_THR, DELTA_MSOC_THR_WORD, DELTA_MSOC_THR_OFFSET, 1, 2048, 100, 0, fg_encode_default, NULL), 1, 2048, 1000, 0, fg_encode_default, NULL), PARAM(DELTA_BSOC_THR, DELTA_BSOC_THR_WORD, DELTA_BSOC_THR_OFFSET, 1, 2048, 100, 0, fg_encode_default, NULL), 1, 2048, 1000, 0, fg_encode_default, NULL), PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD, ESR_TIMER_DISCHG_MAX_OFFSET, 1, 1, 1, 0, fg_encode_default, NULL), Loading Loading @@ -1759,7 +1763,7 @@ static void profile_load_work(struct work_struct *work) struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); int64_t nom_cap_uah; u8 val, buf[2]; u8 val, mask, buf[2]; int rc; vote(fg->awake_votable, PROFILE_LOAD, true, 0); Loading Loading @@ -1802,6 +1806,24 @@ static void profile_load_work(struct work_struct *work) goto out; } /* Enable side loading for voltage and current */ val = mask = BIT(0); rc = fg_sram_masked_write(fg, SYS_CONFIG_WORD, SYS_CONFIG_OFFSET, mask, val, FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in setting SYS_CONFIG_WORD[0], rc=%d\n", rc); goto out; } /* Clear first logged main current ADC values */ buf[0] = buf[1] = 0; rc = fg_sram_write(fg, FIRST_LOG_CURRENT_v2_WORD, FIRST_LOG_CURRENT_v2_OFFSET, buf, 2, FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in clearing FIRST_LOG_CURRENT rc=%d\n", rc); goto out; } /* Set the profile integrity bit */ val = HLOS_RESTART_BIT | PROFILE_LOAD_BIT; rc = fg_sram_write(fg, PROFILE_INTEGRITY_WORD, Loading @@ -1817,6 +1839,16 @@ static void profile_load_work(struct work_struct *work) goto out; } /* Clear side loading for voltage and current */ val = 0; mask = BIT(0); rc = fg_sram_masked_write(fg, SYS_CONFIG_WORD, SYS_CONFIG_OFFSET, mask, val, FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in clearing SYS_CONFIG_WORD[0], rc=%d\n", rc); goto out; } fg_dbg(fg, FG_STATUS, "SOC is ready\n"); fg->profile_load_status = PROFILE_LOADED; Loading Loading @@ -1938,7 +1970,7 @@ static void get_batt_psy_props(struct fg_dev *fg) static int fg_gen4_esr_soh_update(struct fg_dev *fg) { struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); int rc, msoc, esr_uohms; int rc, msoc, esr_uohms, tmp; if (!fg->soc_reporting_ready || fg->battery_missing) { chip->esr_actual = -EINVAL; Loading @@ -1946,14 +1978,28 @@ static int fg_gen4_esr_soh_update(struct fg_dev *fg) return 0; } if (fg->charge_status == POWER_SUPPLY_STATUS_CHARGING) { rc = get_cycle_count(chip->counter, &tmp); if (rc < 0) pr_err("Couldn't get cycle count rc=%d\n", rc); else if (tmp != chip->esr_soh_cycle_count) chip->esr_soh_notified = false; if (fg->charge_status != POWER_SUPPLY_STATUS_CHARGING || chip->esr_soh_notified) return 0; rc = fg_get_msoc(fg, &msoc); if (rc < 0) { pr_err("Error in getting msoc, rc=%d\n", rc); return rc; } if (msoc == ESR_SOH_SOC) { if (msoc != ESR_SOH_SOC) { fg_dbg(fg, FG_STATUS, "msoc: %d, not publishing ESR params\n", msoc); return 0; } rc = fg_get_sram_prop(fg, FG_SRAM_ESR_ACT, &esr_uohms); if (rc < 0) { pr_err("Error in getting esr_actual, rc=%d\n", Loading @@ -1976,8 +2022,12 @@ static int fg_gen4_esr_soh_update(struct fg_dev *fg) if (fg->batt_psy) power_supply_changed(fg->batt_psy); } } rc = get_cycle_count(chip->counter, &chip->esr_soh_cycle_count); if (rc < 0) pr_err("Couldn't get cycle count rc=%d\n", rc); chip->esr_soh_notified = true; return 0; } Loading Loading @@ -2720,10 +2770,13 @@ static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data) { struct fg_dev *fg = data; struct fg_gen4_chip *chip = container_of(fg, struct fg_gen4_chip, fg); int rc, batt_soc, batt_temp; int rc, batt_soc, batt_temp, msoc_raw; bool input_present = is_input_present(fg); fg_dbg(fg, FG_IRQ, "irq %d triggered\n", irq); rc = fg_get_msoc_raw(fg, &msoc_raw); if (!rc) fg_dbg(fg, FG_IRQ, "irq %d triggered msoc_raw: %d\n", irq, msoc_raw); get_batt_psy_props(fg); Loading Loading @@ -3072,6 +3125,7 @@ static void pl_current_en_work(struct work_struct *work) return; vote(chip->parallel_current_en_votable, FG_PARALLEL_EN_VOTER, en, 0); vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, false, 0); } static void pl_enable_work(struct work_struct *work) Loading Loading @@ -3734,7 +3788,6 @@ static int fg_parallel_current_en_cb(struct votable *votable, void *data, fg_dbg(fg, FG_STATUS, "Parallel current summing: %d\n", enable); vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, false, 0); return rc; } Loading Loading @@ -3933,7 +3986,7 @@ static int fg_gen4_hw_init(struct fg_gen4_chip *chip) } } if (chip->dt.delta_soc_thr > 0 && chip->dt.delta_soc_thr < 100) { if (chip->dt.delta_soc_thr > 0 && chip->dt.delta_soc_thr < 125) { fg_encode(fg->sp, FG_SRAM_DELTA_MSOC_THR, chip->dt.delta_soc_thr, buf); rc = fg_sram_write(fg, Loading Loading @@ -4404,7 +4457,7 @@ static void fg_gen4_parse_batt_temp_dt(struct fg_gen4_chip *chip) #define DEFAULT_EMPTY_VOLT_MV 2812 #define DEFAULT_SYS_TERM_CURR_MA -125 #define DEFAULT_CUTOFF_CURR_MA 200 #define DEFAULT_DELTA_SOC_THR 1 #define DEFAULT_DELTA_SOC_THR 5 /* 0.5 % */ #define DEFAULT_CL_START_SOC 15 #define DEFAULT_CL_MIN_TEMP_DECIDEGC 150 #define DEFAULT_CL_MAX_TEMP_DECIDEGC 500 Loading Loading @@ -4714,6 +4767,7 @@ static int fg_gen4_probe(struct platform_device *pdev) fg->batt_id_ohms = -EINVAL; chip->ki_coeff_full_soc[0] = -EINVAL; chip->ki_coeff_full_soc[1] = -EINVAL; chip->esr_soh_cycle_count = -EINVAL; fg->regmap = dev_get_regmap(fg->dev->parent, NULL); if (!fg->regmap) { dev_err(fg->dev, "Parent regmap is unavailable\n"); Loading