summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt7
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmi8998.dtsi1
-rw-r--r--drivers/power/qcom-charger/fg-core.h9
-rw-r--r--drivers/power/qcom-charger/fg-reg.h4
-rw-r--r--drivers/power/qcom-charger/qpnp-fg-gen3.c66
6 files changed, 77 insertions, 11 deletions
diff --git a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt
index 808e18b495d5..baf534695cc1 100644
--- a/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/qcom-charger/qpnp-fg-gen3.txt
@@ -36,6 +36,12 @@ First Level Node - FG Gen3 device
Definition: For details about IIO bindings see:
Documentation/devicetree/bindings/iio/iio-bindings.txt
+- qcom,rradc-base
+ Usage: required
+ Value type: <u32>
+ Definition: Should specify the base address of RR_ADC peripheral. This
+ is used for reading certain peripheral registers under it.
+
- qcom,fg-cutoff-voltage
Usage: optional
Value type: <u32>
@@ -290,6 +296,7 @@ pmi8998_fg: qpnp,fg {
qcom,pmic-revid = <&pmi8998_revid>;
io-channels = <&pmi8998_rradc 3>;
io-channel-names = "rradc_batt_id";
+ qcom,rradc-base = <0x4500>;
qcom,ki-coeff-soc-dischg = <30 60 90>;
qcom,ki-coeff-med-dischg = <800 1000 1400>;
qcom,ki-coeff-hi-dischg = <1200 1500 2100>;
diff --git a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi
index 37e39b776613..0168cb2cddb3 100644
--- a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi
@@ -506,6 +506,7 @@
qcom,pmic-revid = <&pmfalcon_revid>;
io-channels = <&pmfalcon_rradc 0>;
io-channel-names = "rradc_batt_id";
+ qcom,rradc-base = <0x4500>;
qcom,fg-esr-timer-awake = <96>;
qcom,fg-esr-timer-asleep = <256>;
qcom,cycle-counter-en;
diff --git a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
index 0dc9da9289e2..3fa85d918f6c 100644
--- a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
@@ -321,6 +321,7 @@
qcom,pmic-revid = <&pmi8998_revid>;
io-channels = <&pmi8998_rradc 0>;
io-channel-names = "rradc_batt_id";
+ qcom,rradc-base = <0x4500>;
qcom,fg-esr-timer-awake = <96>;
qcom,fg-esr-timer-asleep = <256>;
qcom,cycle-counter-en;
diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h
index 9ddd18800f9d..e284de8bdff1 100644
--- a/drivers/power/qcom-charger/fg-core.h
+++ b/drivers/power/qcom-charger/fg-core.h
@@ -39,6 +39,12 @@
pr_debug(fmt, ##__VA_ARGS__); \
} while (0)
+#define is_between(left, right, value) \
+ (((left) >= (right) && (left) >= (value) \
+ && (value) >= (right)) \
+ || ((left) <= (right) && (left) <= (value) \
+ && (value) <= (right)))
+
/* Awake votable reasons */
#define SRAM_READ "fg_sram_read"
#define SRAM_WRITE "fg_sram_write"
@@ -310,8 +316,9 @@ struct fg_chip {
u32 batt_soc_base;
u32 batt_info_base;
u32 mem_if_base;
+ u32 rradc_base;
u32 wa_flags;
- int batt_id_kohms;
+ int batt_id_ohms;
int charge_status;
int prev_charge_status;
int charge_done;
diff --git a/drivers/power/qcom-charger/fg-reg.h b/drivers/power/qcom-charger/fg-reg.h
index ffc46f328f91..7ad26215e469 100644
--- a/drivers/power/qcom-charger/fg-reg.h
+++ b/drivers/power/qcom-charger/fg-reg.h
@@ -13,6 +13,10 @@
#ifndef __FG_REG_H__
#define __FG_REG_H__
+/* FG_ADC_RR register definitions used only for READ */
+#define ADC_RR_FAKE_BATT_LOW_LSB(chip) (chip->rradc_base + 0x58)
+#define ADC_RR_FAKE_BATT_HIGH_LSB(chip) (chip->rradc_base + 0x5A)
+
/* FG_BATT_SOC register definitions */
#define BATT_SOC_FG_ALG_STS(chip) (chip->batt_soc_base + 0x06)
#define BATT_SOC_FG_ALG_AUX_STS0(chip) (chip->batt_soc_base + 0x07)
diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c
index 74fa041738ff..fbafade817e0 100644
--- a/drivers/power/qcom-charger/qpnp-fg-gen3.c
+++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c
@@ -693,18 +693,57 @@ static bool is_batt_empty(struct fg_chip *chip)
return ((vbatt_uv < chip->dt.cutoff_volt_mv * 1000) ? true : false);
}
-#define DEBUG_BATT_ID_KOHMS 7
+static int fg_get_debug_batt_id(struct fg_chip *chip, int *batt_id)
+{
+ int rc;
+ u64 temp;
+ u8 buf[2];
+
+ rc = fg_read(chip, ADC_RR_FAKE_BATT_LOW_LSB(chip), buf, 2);
+ if (rc < 0) {
+ pr_err("failed to read addr=0x%04x, rc=%d\n",
+ ADC_RR_FAKE_BATT_LOW_LSB(chip), rc);
+ return rc;
+ }
+
+ /*
+ * Fake battery threshold is encoded in the following format.
+ * Threshold (code) = (battery_id in Ohms) * 0.00015 * 2^10 / 2.5
+ */
+ temp = (buf[1] << 8 | buf[0]) * 2500000;
+ do_div(temp, 150 * 1024);
+ batt_id[0] = temp;
+ rc = fg_read(chip, ADC_RR_FAKE_BATT_HIGH_LSB(chip), buf, 2);
+ if (rc < 0) {
+ pr_err("failed to read addr=0x%04x, rc=%d\n",
+ ADC_RR_FAKE_BATT_HIGH_LSB(chip), rc);
+ return rc;
+ }
+
+ temp = (buf[1] << 8 | buf[0]) * 2500000;
+ do_div(temp, 150 * 1024);
+ batt_id[1] = temp;
+ pr_debug("debug batt_id range: [%d %d]\n", batt_id[0], batt_id[1]);
+ return 0;
+}
+
static bool is_debug_batt_id(struct fg_chip *chip)
{
- int batt_id_delta = 0;
+ int debug_batt_id[2], rc;
- if (!chip->batt_id_kohms)
+ if (!chip->batt_id_ohms)
return false;
- batt_id_delta = abs(chip->batt_id_kohms - DEBUG_BATT_ID_KOHMS);
- if (batt_id_delta <= 1) {
- fg_dbg(chip, FG_POWER_SUPPLY, "Debug battery id: %dKohms\n",
- chip->batt_id_kohms);
+ rc = fg_get_debug_batt_id(chip, debug_batt_id);
+ if (rc < 0) {
+ pr_err("Failed to get debug batt_id, rc=%d\n", rc);
+ return false;
+ }
+
+ if (is_between(debug_batt_id[0], debug_batt_id[1],
+ chip->batt_id_ohms)) {
+ fg_dbg(chip, FG_POWER_SUPPLY, "Debug battery id: %dohms\n",
+ chip->batt_id_ohms);
return true;
}
@@ -792,8 +831,8 @@ static int fg_get_batt_profile(struct fg_chip *chip)
return rc;
}
+ chip->batt_id_ohms = batt_id;
batt_id /= 1000;
- chip->batt_id_kohms = batt_id;
batt_node = of_find_node_by_name(node, "qcom,battery-data");
if (!batt_node) {
pr_err("Batterydata not available\n");
@@ -3076,10 +3115,17 @@ static int fg_parse_dt(struct fg_chip *chip)
}
}
+ rc = of_property_read_u32(node, "qcom,rradc-base", &base);
+ if (rc < 0) {
+ dev_err(chip->dev, "rradc-base not specified, rc=%d\n", rc);
+ return rc;
+ }
+ chip->rradc_base = base;
+
rc = fg_get_batt_profile(chip);
if (rc < 0)
pr_warn("profile for batt_id=%dKOhms not found..using OTP, rc:%d\n",
- chip->batt_id_kohms, rc);
+ chip->batt_id_ohms / 1000, rc);
/* Read all the optional properties below */
rc = of_property_read_u32(node, "qcom,fg-cutoff-voltage", &temp);
@@ -3362,7 +3408,7 @@ static int fg_gen3_probe(struct platform_device *pdev)
if (!rc)
pr_info("battery SOC:%d voltage: %duV temp: %d id: %dKOhms\n",
- msoc, volt_uv, batt_temp, chip->batt_id_kohms);
+ msoc, volt_uv, batt_temp, chip->batt_id_ohms / 1000);
device_init_wakeup(chip->dev, true);
if (chip->profile_available)