Loading drivers/power/supply/qcom/qpnp-fg-gen4.c +62 −23 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #define pr_fmt(fmt) "FG: %s: " fmt, __func__ #include <linux/alarmtimer.h> #include <linux/irq.h> #include <linux/ktime.h> #include <linux/of.h> #include <linux/of_platform.h> Loading Loading @@ -244,7 +245,7 @@ struct fg_gen4_chip { struct work_struct esr_calib_work; struct alarm esr_fast_cal_timer; struct delayed_work pl_enable_work; struct delayed_work pl_current_en_work; struct work_struct pl_current_en_work; struct completion mem_attn; char batt_profile[PROFILE_LEN]; enum slope_limit_status slope_limit_sts; Loading Loading @@ -882,6 +883,43 @@ static inline void get_esr_meas_current(int curr_ma, u8 *val) *val <<= ESR_PULL_DOWN_IVAL_SHIFT; } static int fg_gen4_get_power(struct fg_gen4_chip *chip, int *val, bool average) { struct fg_dev *fg = &chip->fg; int rc, v_min, v_pred, esr_uohms, rslow_uohms; s64 power; rc = fg_get_sram_prop(fg, FG_SRAM_VOLTAGE_PRED, &v_pred); if (rc < 0) return rc; v_min = chip->dt.cutoff_volt_mv * 1000; power = (s64)v_min * (v_pred - v_min); rc = fg_get_sram_prop(fg, FG_SRAM_ESR, &esr_uohms); if (rc < 0) { pr_err("failed to get ESR, rc=%d\n", rc); return rc; } rc = fg_get_sram_prop(fg, FG_SRAM_RSLOW, &rslow_uohms); if (rc < 0) { pr_err("failed to get Rslow, rc=%d\n", rc); return rc; } if (average) power = div_s64(power, esr_uohms + rslow_uohms); else power = div_s64(power, esr_uohms); pr_debug("V_min: %d V_pred: %d ESR: %d Rslow: %d power: %lld\n", v_min, v_pred, esr_uohms, rslow_uohms, power); *val = power; return 0; } /* ALG callback functions below */ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val) Loading Loading @@ -3202,31 +3240,16 @@ static void pl_current_en_work(struct work_struct *work) { struct fg_gen4_chip *chip = container_of(work, struct fg_gen4_chip, pl_current_en_work.work); pl_current_en_work); struct fg_dev *fg = &chip->fg; bool input_present = is_input_present(fg), en; en = fg->charge_done ? false : input_present; /* * If mem_attn_irq is disabled and parallel summing current * configuration needs to be modified, then enable mem_attn_irq and * wait for 1 second before doing it. */ if (get_effective_result(chip->parallel_current_en_votable) != en && !get_effective_result(chip->mem_attn_irq_en_votable)) { vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, true, 0); schedule_delayed_work(&chip->pl_current_en_work, msecs_to_jiffies(1000)); return; } if (!get_effective_result(chip->mem_attn_irq_en_votable)) if (get_effective_result(chip->parallel_current_en_votable) == en) 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 @@ -3320,9 +3343,10 @@ static void status_change_work(struct work_struct *work) if (rc < 0) pr_err("Error in adjusting FCC for ESR, rc=%d\n", rc); if (is_parallel_charger_available(fg) && !delayed_work_pending(&chip->pl_current_en_work)) schedule_delayed_work(&chip->pl_current_en_work, 0); if (is_parallel_charger_available(fg)) { cancel_work_sync(&chip->pl_current_en_work); schedule_work(&chip->pl_current_en_work); } ttf_update(chip->ttf, input_present); fg->prev_charge_status = fg->charge_status; Loading Loading @@ -3626,6 +3650,12 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_BATT_AGE_LEVEL: pval->intval = chip->batt_age_level; break; case POWER_SUPPLY_PROP_POWER_NOW: rc = fg_gen4_get_power(chip, &pval->intval, false); break; case POWER_SUPPLY_PROP_POWER_AVG: rc = fg_gen4_get_power(chip, &pval->intval, true); break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; Loading Loading @@ -3773,6 +3803,8 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_CC_STEP, POWER_SUPPLY_PROP_CC_STEP_SEL, POWER_SUPPLY_PROP_BATT_AGE_LEVEL, POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_POWER_AVG, }; static const struct power_supply_desc fg_psy_desc = { Loading Loading @@ -3881,6 +3913,8 @@ static int fg_parallel_current_en_cb(struct votable *votable, void *data, int rc; u8 val, mask; vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, true, 0); /* Wait for MEM_ATTN interrupt */ rc = fg_wait_for_mem_attn(chip); if (rc < 0) Loading @@ -3893,6 +3927,7 @@ static int fg_parallel_current_en_cb(struct votable *votable, void *data, pr_err("Error in writing to 0x%04x, rc=%d\n", BATT_INFO_FG_CNV_CHAR_CFG(fg), rc); vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, false, 0); fg_dbg(fg, FG_STATUS, "Parallel current summing: %d\n", enable); return rc; Loading Loading @@ -4902,7 +4937,7 @@ static void fg_gen4_cleanup(struct fg_gen4_chip *chip) cancel_work(&fg->status_change_work); cancel_delayed_work_sync(&fg->profile_load_work); cancel_delayed_work_sync(&fg->sram_dump_work); cancel_delayed_work_sync(&chip->pl_current_en_work); cancel_work_sync(&chip->pl_current_en_work); power_supply_unreg_notifier(&fg->nb); debugfs_remove_recursive(fg->dfs_root); Loading Loading @@ -4964,7 +4999,7 @@ static int fg_gen4_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&fg->profile_load_work, profile_load_work); INIT_DELAYED_WORK(&fg->sram_dump_work, sram_dump_work); INIT_DELAYED_WORK(&chip->pl_enable_work, pl_enable_work); INIT_DELAYED_WORK(&chip->pl_current_en_work, pl_current_en_work); INIT_WORK(&chip->pl_current_en_work, pl_current_en_work); fg->awake_votable = create_votable("FG_WS", VOTE_SET_ANY, fg_awake_cb, fg); Loading Loading @@ -5078,6 +5113,10 @@ static int fg_gen4_probe(struct platform_device *pdev) goto exit; } if (fg->irqs[MEM_ATTN_IRQ].irq) irq_set_status_flags(fg->irqs[MEM_ATTN_IRQ].irq, IRQ_DISABLE_UNLAZY); /* Keep SOC_UPDATE irq disabled until we require it */ if (fg->irqs[SOC_UPDATE_IRQ].irq) disable_irq_nosync(fg->irqs[SOC_UPDATE_IRQ].irq); Loading Loading
drivers/power/supply/qcom/qpnp-fg-gen4.c +62 −23 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #define pr_fmt(fmt) "FG: %s: " fmt, __func__ #include <linux/alarmtimer.h> #include <linux/irq.h> #include <linux/ktime.h> #include <linux/of.h> #include <linux/of_platform.h> Loading Loading @@ -244,7 +245,7 @@ struct fg_gen4_chip { struct work_struct esr_calib_work; struct alarm esr_fast_cal_timer; struct delayed_work pl_enable_work; struct delayed_work pl_current_en_work; struct work_struct pl_current_en_work; struct completion mem_attn; char batt_profile[PROFILE_LEN]; enum slope_limit_status slope_limit_sts; Loading Loading @@ -882,6 +883,43 @@ static inline void get_esr_meas_current(int curr_ma, u8 *val) *val <<= ESR_PULL_DOWN_IVAL_SHIFT; } static int fg_gen4_get_power(struct fg_gen4_chip *chip, int *val, bool average) { struct fg_dev *fg = &chip->fg; int rc, v_min, v_pred, esr_uohms, rslow_uohms; s64 power; rc = fg_get_sram_prop(fg, FG_SRAM_VOLTAGE_PRED, &v_pred); if (rc < 0) return rc; v_min = chip->dt.cutoff_volt_mv * 1000; power = (s64)v_min * (v_pred - v_min); rc = fg_get_sram_prop(fg, FG_SRAM_ESR, &esr_uohms); if (rc < 0) { pr_err("failed to get ESR, rc=%d\n", rc); return rc; } rc = fg_get_sram_prop(fg, FG_SRAM_RSLOW, &rslow_uohms); if (rc < 0) { pr_err("failed to get Rslow, rc=%d\n", rc); return rc; } if (average) power = div_s64(power, esr_uohms + rslow_uohms); else power = div_s64(power, esr_uohms); pr_debug("V_min: %d V_pred: %d ESR: %d Rslow: %d power: %lld\n", v_min, v_pred, esr_uohms, rslow_uohms, power); *val = power; return 0; } /* ALG callback functions below */ static int fg_gen4_get_ttf_param(void *data, enum ttf_param param, int *val) Loading Loading @@ -3202,31 +3240,16 @@ static void pl_current_en_work(struct work_struct *work) { struct fg_gen4_chip *chip = container_of(work, struct fg_gen4_chip, pl_current_en_work.work); pl_current_en_work); struct fg_dev *fg = &chip->fg; bool input_present = is_input_present(fg), en; en = fg->charge_done ? false : input_present; /* * If mem_attn_irq is disabled and parallel summing current * configuration needs to be modified, then enable mem_attn_irq and * wait for 1 second before doing it. */ if (get_effective_result(chip->parallel_current_en_votable) != en && !get_effective_result(chip->mem_attn_irq_en_votable)) { vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, true, 0); schedule_delayed_work(&chip->pl_current_en_work, msecs_to_jiffies(1000)); return; } if (!get_effective_result(chip->mem_attn_irq_en_votable)) if (get_effective_result(chip->parallel_current_en_votable) == en) 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 @@ -3320,9 +3343,10 @@ static void status_change_work(struct work_struct *work) if (rc < 0) pr_err("Error in adjusting FCC for ESR, rc=%d\n", rc); if (is_parallel_charger_available(fg) && !delayed_work_pending(&chip->pl_current_en_work)) schedule_delayed_work(&chip->pl_current_en_work, 0); if (is_parallel_charger_available(fg)) { cancel_work_sync(&chip->pl_current_en_work); schedule_work(&chip->pl_current_en_work); } ttf_update(chip->ttf, input_present); fg->prev_charge_status = fg->charge_status; Loading Loading @@ -3626,6 +3650,12 @@ static int fg_psy_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_BATT_AGE_LEVEL: pval->intval = chip->batt_age_level; break; case POWER_SUPPLY_PROP_POWER_NOW: rc = fg_gen4_get_power(chip, &pval->intval, false); break; case POWER_SUPPLY_PROP_POWER_AVG: rc = fg_gen4_get_power(chip, &pval->intval, true); break; default: pr_err("unsupported property %d\n", psp); rc = -EINVAL; Loading Loading @@ -3773,6 +3803,8 @@ static enum power_supply_property fg_psy_props[] = { POWER_SUPPLY_PROP_CC_STEP, POWER_SUPPLY_PROP_CC_STEP_SEL, POWER_SUPPLY_PROP_BATT_AGE_LEVEL, POWER_SUPPLY_PROP_POWER_NOW, POWER_SUPPLY_PROP_POWER_AVG, }; static const struct power_supply_desc fg_psy_desc = { Loading Loading @@ -3881,6 +3913,8 @@ static int fg_parallel_current_en_cb(struct votable *votable, void *data, int rc; u8 val, mask; vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, true, 0); /* Wait for MEM_ATTN interrupt */ rc = fg_wait_for_mem_attn(chip); if (rc < 0) Loading @@ -3893,6 +3927,7 @@ static int fg_parallel_current_en_cb(struct votable *votable, void *data, pr_err("Error in writing to 0x%04x, rc=%d\n", BATT_INFO_FG_CNV_CHAR_CFG(fg), rc); vote(chip->mem_attn_irq_en_votable, MEM_ATTN_IRQ_VOTER, false, 0); fg_dbg(fg, FG_STATUS, "Parallel current summing: %d\n", enable); return rc; Loading Loading @@ -4902,7 +4937,7 @@ static void fg_gen4_cleanup(struct fg_gen4_chip *chip) cancel_work(&fg->status_change_work); cancel_delayed_work_sync(&fg->profile_load_work); cancel_delayed_work_sync(&fg->sram_dump_work); cancel_delayed_work_sync(&chip->pl_current_en_work); cancel_work_sync(&chip->pl_current_en_work); power_supply_unreg_notifier(&fg->nb); debugfs_remove_recursive(fg->dfs_root); Loading Loading @@ -4964,7 +4999,7 @@ static int fg_gen4_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&fg->profile_load_work, profile_load_work); INIT_DELAYED_WORK(&fg->sram_dump_work, sram_dump_work); INIT_DELAYED_WORK(&chip->pl_enable_work, pl_enable_work); INIT_DELAYED_WORK(&chip->pl_current_en_work, pl_current_en_work); INIT_WORK(&chip->pl_current_en_work, pl_current_en_work); fg->awake_votable = create_votable("FG_WS", VOTE_SET_ANY, fg_awake_cb, fg); Loading Loading @@ -5078,6 +5113,10 @@ static int fg_gen4_probe(struct platform_device *pdev) goto exit; } if (fg->irqs[MEM_ATTN_IRQ].irq) irq_set_status_flags(fg->irqs[MEM_ATTN_IRQ].irq, IRQ_DISABLE_UNLAZY); /* Keep SOC_UPDATE irq disabled until we require it */ if (fg->irqs[SOC_UPDATE_IRQ].irq) disable_irq_nosync(fg->irqs[SOC_UPDATE_IRQ].irq); Loading