Loading drivers/power/supply/qcom/fg-core.h +20 −5 Original line number Diff line number Diff line Loading @@ -128,11 +128,6 @@ enum fg_irq_index { FG_IRQ_MAX, }; /* WA flags */ enum { DELTA_SOC_IRQ_WA = BIT(0), }; /* * List of FG_SRAM parameters. Please add a parameter only if it is an entry * that will be used either to configure an entity (e.g. termination current) Loading @@ -152,6 +147,7 @@ enum fg_sram_param_id { FG_SRAM_CC_SOC, FG_SRAM_CC_SOC_SW, FG_SRAM_ACT_BATT_CAP, FG_SRAM_TIMEBASE, /* Entries below here are configurable during initialization */ FG_SRAM_CUTOFF_VOLT, FG_SRAM_EMPTY_VOLT, Loading Loading @@ -212,6 +208,7 @@ struct fg_alg_flag { enum wa_flags { PMI8998_V1_REV_WA = BIT(0), PM660_TSMC_OSC_WA = BIT(1), }; enum slope_limit_status { Loading Loading @@ -325,6 +322,23 @@ static const struct fg_pt fg_ln_table[] = { { 128000, 4852 }, }; /* each tuple is - <temperature in degC, Timebase> */ static const struct fg_pt fg_tsmc_osc_table[] = { { -20, 395064 }, { -10, 398114 }, { 0, 401669 }, { 10, 404641 }, { 20, 408856 }, { 25, 412449 }, { 30, 416532 }, { 40, 420289 }, { 50, 425020 }, { 60, 430160 }, { 70, 434175 }, { 80, 439475 }, { 90, 444992 }, }; struct fg_chip { struct device *dev; struct pmic_revid_data *pmic_rev_id; Loading @@ -336,6 +350,7 @@ struct fg_chip { struct power_supply *dc_psy; struct power_supply *parallel_psy; struct iio_channel *batt_id_chan; struct iio_channel *die_temp_chan; struct fg_memif *sram; struct fg_irq_info *irqs; struct votable *awake_votable; Loading drivers/power/supply/qcom/qpnp-fg-gen3.c +62 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ #define ESR_UPD_TIGHT_LOW_TEMP_OFFSET 2 #define ESR_UPD_BROAD_LOW_TEMP_OFFSET 3 #define KI_COEFF_MED_DISCHG_WORD 9 #define TIMEBASE_OFFSET 1 #define KI_COEFF_MED_DISCHG_OFFSET 3 #define KI_COEFF_HI_DISCHG_WORD 10 #define KI_COEFF_HI_DISCHG_OFFSET 0 Loading Loading @@ -261,6 +262,8 @@ static struct fg_sram_param pmi8998_v2_sram_params[] = { fg_decode_cc_soc), PARAM(ACT_BATT_CAP, ACT_BATT_CAP_BKUP_WORD, ACT_BATT_CAP_BKUP_OFFSET, 2, 1, 1, 0, NULL, fg_decode_default), PARAM(TIMEBASE, KI_COEFF_MED_DISCHG_WORD, TIMEBASE_OFFSET, 2, 1000, 61000, 0, fg_encode_default, NULL), /* Entries below here are configurable during initialization */ PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000, 244141, 0, fg_encode_voltage, NULL), Loading Loading @@ -3365,6 +3368,40 @@ static int fg_memif_init(struct fg_chip *chip) return fg_ima_init(chip); } static int fg_adjust_timebase(struct fg_chip *chip) { int rc = 0, die_temp; s32 time_base = 0; u8 buf[2] = {0}; if ((chip->wa_flags & PM660_TSMC_OSC_WA) && chip->die_temp_chan) { rc = iio_read_channel_processed(chip->die_temp_chan, &die_temp); if (rc < 0) { pr_err("Error in reading die_temp, rc:%d\n", rc); return rc; } rc = fg_lerp(fg_tsmc_osc_table, ARRAY_SIZE(fg_tsmc_osc_table), die_temp / 1000, &time_base); if (rc < 0) { pr_err("Error to lookup fg_tsmc_osc_table rc=%d\n", rc); return rc; } fg_encode(chip->sp, FG_SRAM_TIMEBASE, time_base, buf); rc = fg_sram_write(chip, chip->sp[FG_SRAM_TIMEBASE].addr_word, chip->sp[FG_SRAM_TIMEBASE].addr_byte, buf, chip->sp[FG_SRAM_TIMEBASE].len, FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in writing timebase, rc=%d\n", rc); return rc; } } return 0; } /* INTERRUPT HANDLERS STAY HERE */ static irqreturn_t fg_mem_xcp_irq_handler(int irq, void *data) Loading Loading @@ -3486,6 +3523,10 @@ static irqreturn_t fg_delta_batt_temp_irq_handler(int irq, void *data) chip->health = prop.intval; if (chip->last_batt_temp != batt_temp) { rc = fg_adjust_timebase(chip); if (rc < 0) pr_err("Error in adjusting timebase, rc=%d\n", rc); chip->last_batt_temp = batt_temp; power_supply_changed(chip->batt_psy); } Loading Loading @@ -3555,6 +3596,10 @@ static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data) if (rc < 0) pr_err("Error in validating ESR, rc=%d\n", rc); rc = fg_adjust_timebase(chip); if (rc < 0) pr_err("Error in adjusting timebase, rc=%d\n", rc); if (batt_psy_initialized(chip)) power_supply_changed(chip->batt_psy); Loading Loading @@ -3897,6 +3942,8 @@ static int fg_parse_dt(struct fg_chip *chip) chip->sp = pmi8998_v2_sram_params; chip->alg_flags = pmi8998_v2_alg_flags; chip->use_ima_single_mode = true; if (chip->pmic_rev_id->fab_id == PM660_FAB_ID_TSMC) chip->wa_flags |= PM660_TSMC_OSC_WA; break; default: return -EINVAL; Loading Loading @@ -4238,6 +4285,21 @@ static int fg_gen3_probe(struct platform_device *pdev) return rc; } rc = of_property_match_string(chip->dev->of_node, "io-channel-names", "rradc_die_temp"); if (rc >= 0) { chip->die_temp_chan = iio_channel_get(chip->dev, "rradc_die_temp"); if (IS_ERR(chip->die_temp_chan)) { if (PTR_ERR(chip->die_temp_chan) != -EPROBE_DEFER) pr_err("rradc_die_temp unavailable %ld\n", PTR_ERR(chip->die_temp_chan)); rc = PTR_ERR(chip->die_temp_chan); chip->die_temp_chan = NULL; return rc; } } chip->awake_votable = create_votable("FG_WS", VOTE_SET_ANY, fg_awake_cb, chip); if (IS_ERR(chip->awake_votable)) { Loading Loading
drivers/power/supply/qcom/fg-core.h +20 −5 Original line number Diff line number Diff line Loading @@ -128,11 +128,6 @@ enum fg_irq_index { FG_IRQ_MAX, }; /* WA flags */ enum { DELTA_SOC_IRQ_WA = BIT(0), }; /* * List of FG_SRAM parameters. Please add a parameter only if it is an entry * that will be used either to configure an entity (e.g. termination current) Loading @@ -152,6 +147,7 @@ enum fg_sram_param_id { FG_SRAM_CC_SOC, FG_SRAM_CC_SOC_SW, FG_SRAM_ACT_BATT_CAP, FG_SRAM_TIMEBASE, /* Entries below here are configurable during initialization */ FG_SRAM_CUTOFF_VOLT, FG_SRAM_EMPTY_VOLT, Loading Loading @@ -212,6 +208,7 @@ struct fg_alg_flag { enum wa_flags { PMI8998_V1_REV_WA = BIT(0), PM660_TSMC_OSC_WA = BIT(1), }; enum slope_limit_status { Loading Loading @@ -325,6 +322,23 @@ static const struct fg_pt fg_ln_table[] = { { 128000, 4852 }, }; /* each tuple is - <temperature in degC, Timebase> */ static const struct fg_pt fg_tsmc_osc_table[] = { { -20, 395064 }, { -10, 398114 }, { 0, 401669 }, { 10, 404641 }, { 20, 408856 }, { 25, 412449 }, { 30, 416532 }, { 40, 420289 }, { 50, 425020 }, { 60, 430160 }, { 70, 434175 }, { 80, 439475 }, { 90, 444992 }, }; struct fg_chip { struct device *dev; struct pmic_revid_data *pmic_rev_id; Loading @@ -336,6 +350,7 @@ struct fg_chip { struct power_supply *dc_psy; struct power_supply *parallel_psy; struct iio_channel *batt_id_chan; struct iio_channel *die_temp_chan; struct fg_memif *sram; struct fg_irq_info *irqs; struct votable *awake_votable; Loading
drivers/power/supply/qcom/qpnp-fg-gen3.c +62 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ #define ESR_UPD_TIGHT_LOW_TEMP_OFFSET 2 #define ESR_UPD_BROAD_LOW_TEMP_OFFSET 3 #define KI_COEFF_MED_DISCHG_WORD 9 #define TIMEBASE_OFFSET 1 #define KI_COEFF_MED_DISCHG_OFFSET 3 #define KI_COEFF_HI_DISCHG_WORD 10 #define KI_COEFF_HI_DISCHG_OFFSET 0 Loading Loading @@ -261,6 +262,8 @@ static struct fg_sram_param pmi8998_v2_sram_params[] = { fg_decode_cc_soc), PARAM(ACT_BATT_CAP, ACT_BATT_CAP_BKUP_WORD, ACT_BATT_CAP_BKUP_OFFSET, 2, 1, 1, 0, NULL, fg_decode_default), PARAM(TIMEBASE, KI_COEFF_MED_DISCHG_WORD, TIMEBASE_OFFSET, 2, 1000, 61000, 0, fg_encode_default, NULL), /* Entries below here are configurable during initialization */ PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000, 244141, 0, fg_encode_voltage, NULL), Loading Loading @@ -3365,6 +3368,40 @@ static int fg_memif_init(struct fg_chip *chip) return fg_ima_init(chip); } static int fg_adjust_timebase(struct fg_chip *chip) { int rc = 0, die_temp; s32 time_base = 0; u8 buf[2] = {0}; if ((chip->wa_flags & PM660_TSMC_OSC_WA) && chip->die_temp_chan) { rc = iio_read_channel_processed(chip->die_temp_chan, &die_temp); if (rc < 0) { pr_err("Error in reading die_temp, rc:%d\n", rc); return rc; } rc = fg_lerp(fg_tsmc_osc_table, ARRAY_SIZE(fg_tsmc_osc_table), die_temp / 1000, &time_base); if (rc < 0) { pr_err("Error to lookup fg_tsmc_osc_table rc=%d\n", rc); return rc; } fg_encode(chip->sp, FG_SRAM_TIMEBASE, time_base, buf); rc = fg_sram_write(chip, chip->sp[FG_SRAM_TIMEBASE].addr_word, chip->sp[FG_SRAM_TIMEBASE].addr_byte, buf, chip->sp[FG_SRAM_TIMEBASE].len, FG_IMA_DEFAULT); if (rc < 0) { pr_err("Error in writing timebase, rc=%d\n", rc); return rc; } } return 0; } /* INTERRUPT HANDLERS STAY HERE */ static irqreturn_t fg_mem_xcp_irq_handler(int irq, void *data) Loading Loading @@ -3486,6 +3523,10 @@ static irqreturn_t fg_delta_batt_temp_irq_handler(int irq, void *data) chip->health = prop.intval; if (chip->last_batt_temp != batt_temp) { rc = fg_adjust_timebase(chip); if (rc < 0) pr_err("Error in adjusting timebase, rc=%d\n", rc); chip->last_batt_temp = batt_temp; power_supply_changed(chip->batt_psy); } Loading Loading @@ -3555,6 +3596,10 @@ static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data) if (rc < 0) pr_err("Error in validating ESR, rc=%d\n", rc); rc = fg_adjust_timebase(chip); if (rc < 0) pr_err("Error in adjusting timebase, rc=%d\n", rc); if (batt_psy_initialized(chip)) power_supply_changed(chip->batt_psy); Loading Loading @@ -3897,6 +3942,8 @@ static int fg_parse_dt(struct fg_chip *chip) chip->sp = pmi8998_v2_sram_params; chip->alg_flags = pmi8998_v2_alg_flags; chip->use_ima_single_mode = true; if (chip->pmic_rev_id->fab_id == PM660_FAB_ID_TSMC) chip->wa_flags |= PM660_TSMC_OSC_WA; break; default: return -EINVAL; Loading Loading @@ -4238,6 +4285,21 @@ static int fg_gen3_probe(struct platform_device *pdev) return rc; } rc = of_property_match_string(chip->dev->of_node, "io-channel-names", "rradc_die_temp"); if (rc >= 0) { chip->die_temp_chan = iio_channel_get(chip->dev, "rradc_die_temp"); if (IS_ERR(chip->die_temp_chan)) { if (PTR_ERR(chip->die_temp_chan) != -EPROBE_DEFER) pr_err("rradc_die_temp unavailable %ld\n", PTR_ERR(chip->die_temp_chan)); rc = PTR_ERR(chip->die_temp_chan); chip->die_temp_chan = NULL; return rc; } } chip->awake_votable = create_votable("FG_WS", VOTE_SET_ANY, fg_awake_cb, chip); if (IS_ERR(chip->awake_votable)) { Loading