diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2017-04-12 16:10:09 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-04-12 16:10:09 -0700 |
| commit | 0a2d2c47a82e63653b5b59c3b196890ba95f23bc (patch) | |
| tree | 46f3d5b1fcf2d8a0edf5b3f44625c4b48f4dc394 | |
| parent | f6b72aa023b182d8088aae60f365c2242568558f (diff) | |
| parent | 97a28dd890e2931cb00e83965b7e758264b7d99b (diff) | |
Merge "ARM: dts: msm: Add RRADC die-temp channel for PM660 FG"
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm-pm660.dtsi | 6 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/fg-core.h | 25 | ||||
| -rw-r--r-- | drivers/power/supply/qcom/qpnp-fg-gen3.c | 62 |
3 files changed, 86 insertions, 7 deletions
diff --git a/arch/arm/boot/dts/qcom/msm-pm660.dtsi b/arch/arm/boot/dts/qcom/msm-pm660.dtsi index 5c0010d26a8a..f20238123bca 100644 --- a/arch/arm/boot/dts/qcom/msm-pm660.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm660.dtsi @@ -539,8 +539,10 @@ #address-cells = <1>; #size-cells = <1>; qcom,pmic-revid = <&pm660_revid>; - io-channels = <&pm660_rradc 0>; - io-channel-names = "rradc_batt_id"; + io-channels = <&pm660_rradc 0>, + <&pm660_rradc 7>; + io-channel-names = "rradc_batt_id", + "rradc_die_temp"; qcom,rradc-base = <0x4500>; qcom,fg-esr-timer-awake = <96>; qcom,fg-esr-timer-asleep = <256>; diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h index 316313ff6408..f35864183635 100644 --- a/drivers/power/supply/qcom/fg-core.h +++ b/drivers/power/supply/qcom/fg-core.h @@ -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) @@ -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, @@ -210,6 +206,7 @@ struct fg_alg_flag { enum wa_flags { PMI8998_V1_REV_WA = BIT(0), + PM660_TSMC_OSC_WA = BIT(1), }; enum slope_limit_status { @@ -322,6 +319,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; @@ -333,6 +347,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; diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c index 2e9425040f72..8cc67b4e6ff2 100644 --- a/drivers/power/supply/qcom/qpnp-fg-gen3.c +++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c @@ -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 @@ -255,6 +256,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), @@ -3302,6 +3305,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) @@ -3419,6 +3456,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); } @@ -3488,6 +3529,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); @@ -3829,6 +3874,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; @@ -4163,6 +4210,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)) { |
