summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubbaraman Narayanamurthy <subbaram@codeaurora.org>2017-02-24 16:04:46 -0800
committerSubbaraman Narayanamurthy <subbaram@codeaurora.org>2017-02-28 20:06:09 -0800
commitc7d377aa837e1c015d72e5d918635eccbdf2741a (patch)
tree8262752dfce056ffc23c42b29a9d808ff44760c4
parentf419890fd6558b73f835457246666d6ab8c34d7a (diff)
power: qpnp-fg-gen3: Add support to clamp ESR
If ESR value goes to 0 because of some hardware issue, there is no way to recover it back from that state. This causes incorrect SOC reporting leading to a bad user experience. Hence add support to clamp ESR value based on user defined DT property so that ESR can be clamped to this value once it is found to go below it. Since this change modifies ESR value in SRAM, having FG_SRAM_ESR property would make encode and decode the value easier. Hence remove fg_get_battery_esr() and get it from FG_SRAM_ESR property. CRs-Fixed: 2011200 Change-Id: I96250b44f52d6208f3c64fb9e61f70ea41f54f4e Signed-off-by: Subbaraman Narayanamurthy <subbaram@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt8
-rw-r--r--drivers/power/supply/qcom/fg-core.h2
-rw-r--r--drivers/power/supply/qcom/qpnp-fg-gen3.c81
3 files changed, 62 insertions, 29 deletions
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
index af80de7f5f1f..9638888ebc9e 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
@@ -278,6 +278,14 @@ First Level Node - FG Gen3 device
is specified, then ESR to Rslow scaling factors will be
updated to account it for an accurate ESR.
+- qcom,fg-esr-clamp-mohms
+ Usage: optional
+ Value type: <u32>
+ Definition: Equivalent series resistance (ESR) in milliohms. If this
+ is specified, then ESR will be clamped to this value when
+ ESR is found to be dropping below this. Default value is
+ 20.
+
- qcom,fg-esr-filter-switch-temp
Usage: optional
Value type: <u32>
diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h
index c146654e438b..32a25b4e2c7b 100644
--- a/drivers/power/supply/qcom/fg-core.h
+++ b/drivers/power/supply/qcom/fg-core.h
@@ -143,6 +143,7 @@ enum fg_sram_param_id {
FG_SRAM_FULL_SOC,
FG_SRAM_VOLTAGE_PRED,
FG_SRAM_OCV,
+ FG_SRAM_ESR,
FG_SRAM_RSLOW,
FG_SRAM_ALG_FLAGS,
FG_SRAM_CC_SOC,
@@ -233,6 +234,7 @@ struct fg_dt_props {
int esr_timer_awake;
int esr_timer_asleep;
int rconn_mohms;
+ int esr_clamp_mohms;
int cl_start_soc;
int cl_max_temp;
int cl_min_temp;
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index 1fd092c550f3..39afc235fbc3 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -99,6 +99,8 @@
#define VOLTAGE_PRED_OFFSET 0
#define OCV_WORD 97
#define OCV_OFFSET 2
+#define ESR_WORD 99
+#define ESR_OFFSET 0
#define RSLOW_WORD 101
#define RSLOW_OFFSET 0
#define ACT_BATT_CAP_WORD 117
@@ -173,6 +175,8 @@ static struct fg_sram_param pmi8998_v1_sram_params[] = {
244141, 0, NULL, fg_decode_voltage_15b),
PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 1000, 244141, 0, NULL,
fg_decode_voltage_15b),
+ PARAM(ESR, ESR_WORD, ESR_OFFSET, 2, 1000, 244141, 0, fg_encode_default,
+ fg_decode_value_16b),
PARAM(RSLOW, RSLOW_WORD, RSLOW_OFFSET, 2, 1000, 244141, 0, NULL,
fg_decode_value_16b),
PARAM(ALG_FLAGS, ALG_FLAGS_WORD, ALG_FLAGS_OFFSET, 1, 1, 1, 0, NULL,
@@ -235,6 +239,8 @@ static struct fg_sram_param pmi8998_v2_sram_params[] = {
244141, 0, NULL, fg_decode_voltage_15b),
PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 1000, 244141, 0, NULL,
fg_decode_voltage_15b),
+ PARAM(ESR, ESR_WORD, ESR_OFFSET, 2, 1000, 244141, 0, fg_encode_default,
+ fg_decode_value_16b),
PARAM(RSLOW, RSLOW_WORD, RSLOW_OFFSET, 2, 1000, 244141, 0, NULL,
fg_decode_value_16b),
PARAM(ALG_FLAGS, ALG_FLAGS_WORD, ALG_FLAGS_OFFSET, 1, 1, 1, 0, NULL,
@@ -571,38 +577,11 @@ static int fg_get_battery_temp(struct fg_chip *chip, int *val)
return 0;
}
-#define BATT_ESR_NUMR 244141
-#define BATT_ESR_DENR 1000
-static int fg_get_battery_esr(struct fg_chip *chip, int *val)
-{
- int rc = 0;
- u16 temp = 0;
- u8 buf[2];
-
- rc = fg_read(chip, BATT_INFO_ESR_LSB(chip), buf, 2);
- if (rc < 0) {
- pr_err("failed to read addr=0x%04x, rc=%d\n",
- BATT_INFO_ESR_LSB(chip), rc);
- return rc;
- }
-
- if (chip->wa_flags & PMI8998_V1_REV_WA)
- temp = ((buf[0] & ESR_MSB_MASK) << 8) |
- (buf[1] & ESR_LSB_MASK);
- else
- temp = ((buf[1] & ESR_MSB_MASK) << 8) |
- (buf[0] & ESR_LSB_MASK);
-
- pr_debug("buf: %x %x temp: %x\n", buf[0], buf[1], temp);
- *val = div_u64((u64)temp * BATT_ESR_NUMR, BATT_ESR_DENR);
- return 0;
-}
-
static int fg_get_battery_resistance(struct fg_chip *chip, int *val)
{
int rc, esr_uohms, rslow_uohms;
- rc = fg_get_battery_esr(chip, &esr_uohms);
+ rc = fg_get_sram_prop(chip, FG_SRAM_ESR, &esr_uohms);
if (rc < 0) {
pr_err("failed to get ESR, rc=%d\n", rc);
return rc;
@@ -1631,7 +1610,7 @@ static int fg_rconn_config(struct fg_chip *chip)
return 0;
}
- rc = fg_get_battery_esr(chip, &esr_uohms);
+ rc = fg_get_sram_prop(chip, FG_SRAM_ESR, &esr_uohms);
if (rc < 0) {
pr_err("failed to get ESR, rc=%d\n", rc);
return rc;
@@ -2744,6 +2723,39 @@ out:
return rc;
}
+static int fg_esr_validate(struct fg_chip *chip)
+{
+ int rc, esr_uohms;
+ u8 buf[2];
+
+ if (chip->dt.esr_clamp_mohms <= 0)
+ return 0;
+
+ rc = fg_get_sram_prop(chip, FG_SRAM_ESR, &esr_uohms);
+ if (rc < 0) {
+ pr_err("failed to get ESR, rc=%d\n", rc);
+ return rc;
+ }
+
+ if (esr_uohms >= chip->dt.esr_clamp_mohms * 1000) {
+ pr_debug("ESR %d is > ESR_clamp\n", esr_uohms);
+ return 0;
+ }
+
+ esr_uohms = chip->dt.esr_clamp_mohms * 1000;
+ fg_encode(chip->sp, FG_SRAM_ESR, esr_uohms, buf);
+ rc = fg_sram_write(chip, chip->sp[FG_SRAM_ESR].addr_word,
+ chip->sp[FG_SRAM_ESR].addr_byte, buf,
+ chip->sp[FG_SRAM_ESR].len, FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in writing ESR, rc=%d\n", rc);
+ return rc;
+ }
+
+ fg_dbg(chip, FG_STATUS, "ESR clamped to %duOhms\n", esr_uohms);
+ return 0;
+}
+
/* PSY CALLBACKS STAY HERE */
static int fg_psy_get_property(struct power_supply *psy,
@@ -3371,6 +3383,10 @@ static irqreturn_t fg_delta_msoc_irq_handler(int irq, void *data)
if (rc < 0)
pr_err("Error in updating maint_soc, rc=%d\n", rc);
+ rc = fg_esr_validate(chip);
+ if (rc < 0)
+ pr_err("Error in validating ESR, rc=%d\n", rc);
+
if (batt_psy_initialized(chip))
power_supply_changed(chip->batt_psy);
@@ -3659,6 +3675,7 @@ static int fg_parse_ki_coefficients(struct fg_chip *chip)
#define DEFAULT_ESR_BROAD_FLT_UPCT 99610
#define DEFAULT_ESR_TIGHT_LT_FLT_UPCT 48829
#define DEFAULT_ESR_BROAD_LT_FLT_UPCT 148438
+#define DEFAULT_ESR_CLAMP_MOHMS 20
static int fg_parse_dt(struct fg_chip *chip)
{
struct device_node *child, *revid_node, *node = chip->dev->of_node;
@@ -3972,6 +3989,12 @@ static int fg_parse_dt(struct fg_chip *chip)
if (rc < 0)
pr_err("Error in parsing slope limit coeffs, rc=%d\n", rc);
+ rc = of_property_read_u32(node, "qcom,fg-esr-clamp-mohms", &temp);
+ if (rc < 0)
+ chip->dt.esr_clamp_mohms = DEFAULT_ESR_CLAMP_MOHMS;
+ else
+ chip->dt.esr_clamp_mohms = temp;
+
return 0;
}