diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2016-12-19 00:44:54 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-12-19 00:44:53 -0800 |
commit | 9e4aaa1b8e1708174ed0fed5767f5d96e5b63475 (patch) | |
tree | c260e4283ef690934400e60d303eb2b4bbd4ec82 /drivers/power | |
parent | dae50ed91db84d57ead26c5358ceda57257c9cf3 (diff) | |
parent | 37a8348b873cba82c8c84f1bcacbc9f9fcaedb05 (diff) |
Merge "qpnp-fg-gen3: Read debug battery id thresholds from RR_ADC registers"
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/qcom-charger/fg-core.h | 9 | ||||
-rw-r--r-- | drivers/power/qcom-charger/fg-reg.h | 4 | ||||
-rw-r--r-- | drivers/power/qcom-charger/qpnp-fg-gen3.c | 66 |
3 files changed, 68 insertions, 11 deletions
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) |