summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Troast <ntroast@codeaurora.org>2016-08-15 10:45:39 -0700
committerNicholas Troast <ntroast@codeaurora.org>2016-08-24 15:23:43 -0700
commitca38df6d395f269a49bd51ef4ae0bc9b6f8dd5ea (patch)
tree3604f4fd33c12c337b0673c4ed79239fc53a1e8f
parentc605e110ab18604981481a7b502da54640b620bc (diff)
qcom-charger: qpnp-fg-gen3: add v2 SRAM register map
The location of some fuel gauge SRAM registers have changed in PMICOBALT v2. Add a new SRAM register map for v2 to handle these changes. Change-Id: I1fcfce8e56b1d4e8b8f54457193cd547fb5e3de7 Signed-off-by: Nicholas Troast <ntroast@codeaurora.org>
-rw-r--r--drivers/power/qcom-charger/fg-core.h5
-rw-r--r--drivers/power/qcom-charger/qpnp-fg-gen3.c165
2 files changed, 103 insertions, 67 deletions
diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h
index d176bbb7d872..08ec7334737e 100644
--- a/drivers/power/qcom-charger/fg-core.h
+++ b/drivers/power/qcom-charger/fg-core.h
@@ -130,12 +130,13 @@ enum fg_sram_param_id {
};
struct fg_sram_param {
- u16 address;
- int offset;
+ u16 addr_word;
+ int addr_byte;
u8 len;
int value;
int numrtr;
int denmtr;
+ int offset;
void (*encode)(struct fg_sram_param *sp, enum fg_sram_param_id id,
int val, u8 *buf);
int (*decode)(struct fg_sram_param *sp, enum fg_sram_param_id id,
diff --git a/drivers/power/qcom-charger/qpnp-fg-gen3.c b/drivers/power/qcom-charger/qpnp-fg-gen3.c
index fcd4545471cc..29b9519bd541 100644
--- a/drivers/power/qcom-charger/qpnp-fg-gen3.c
+++ b/drivers/power/qcom-charger/qpnp-fg-gen3.c
@@ -74,63 +74,113 @@
#define LAST_MONOTONIC_SOC_WORD 119
#define LAST_MONOTONIC_SOC_OFFSET 2
+/* v2 SRAM address and offset in ascending order */
+#define DELTA_SOC_THR_v2_WORD 13
+#define DELTA_SOC_THR_v2_OFFSET 0
+#define RECHARGE_SOC_THR_v2_WORD 14
+#define RECHARGE_SOC_THR_v2_OFFSET 1
+#define CHG_TERM_CURR_v2_WORD 15
+#define CHG_TERM_CURR_v2_OFFSET 1
+#define EMPTY_VOLT_v2_WORD 15
+#define EMPTY_VOLT_v2_OFFSET 2
+#define VBATT_LOW_v2_WORD 16
+#define VBATT_LOW_v2_OFFSET 0
+
static int fg_decode_value_16b(struct fg_sram_param *sp,
enum fg_sram_param_id id, int val);
static int fg_decode_default(struct fg_sram_param *sp,
enum fg_sram_param_id id, int val);
-static void fg_encode_voltage_16b(struct fg_sram_param *sp,
- enum fg_sram_param_id id, int val, u8 *buf);
-static void fg_encode_voltage_8b(struct fg_sram_param *sp,
+static void fg_encode_voltage(struct fg_sram_param *sp,
enum fg_sram_param_id id, int val, u8 *buf);
static void fg_encode_current(struct fg_sram_param *sp,
enum fg_sram_param_id id, int val, u8 *buf);
static void fg_encode_default(struct fg_sram_param *sp,
enum fg_sram_param_id id, int val, u8 *buf);
-#define PARAM(_id, _addr, _offset, _len, _num, _den, _enc, _dec) \
+#define PARAM(_id, _addr_word, _addr_byte, _len, _num, _den, _offset, \
+ _enc, _dec) \
[FG_SRAM_##_id] = { \
- .address = _addr, \
- .offset = _offset, \
- .len = _len, \
- .numrtr = _num, \
- .denmtr = _den, \
- .encode = _enc, \
- .decode = _dec, \
+ .addr_word = _addr_word, \
+ .addr_byte = _addr_byte, \
+ .len = _len, \
+ .numrtr = _num, \
+ .denmtr = _den, \
+ .offset = _offset, \
+ .encode = _enc, \
+ .decode = _dec, \
} \
static struct fg_sram_param pmicobalt_v1_sram_params[] = {
- PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, NULL,
+ PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, 0, NULL,
fg_decode_default),
PARAM(VOLTAGE_PRED, VOLTAGE_PRED_WORD, VOLTAGE_PRED_OFFSET, 2, 244141,
- 1000, NULL, fg_decode_value_16b),
- PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 244141, 1000, NULL,
+ 1000, 0, NULL, fg_decode_value_16b),
+ PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 244141, 1000, 0, NULL,
fg_decode_value_16b),
- PARAM(RSLOW, RSLOW_WORD, RSLOW_OFFSET, 2, 244141, 1000, NULL,
+ PARAM(RSLOW, RSLOW_WORD, RSLOW_OFFSET, 2, 244141, 1000, 0, NULL,
fg_decode_value_16b),
/* Entries below here are configurable during initialization */
PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000,
- 244141, fg_encode_voltage_16b, NULL),
+ 244141, 0, fg_encode_voltage, NULL),
PARAM(EMPTY_VOLT, EMPTY_VOLT_WORD, EMPTY_VOLT_OFFSET, 1, 100000, 390625,
- fg_encode_voltage_8b, NULL),
+ -2500, fg_encode_voltage, NULL),
PARAM(VBATT_LOW, VBATT_LOW_WORD, VBATT_LOW_OFFSET, 1, 100000, 390625,
- fg_encode_voltage_8b, NULL),
+ -2500, fg_encode_voltage, NULL),
PARAM(SYS_TERM_CURR, SYS_TERM_CURR_WORD, SYS_TERM_CURR_OFFSET, 3,
- 1000000, 122070, fg_encode_current, NULL),
+ 1000000, 122070, 0, fg_encode_current, NULL),
PARAM(CHG_TERM_CURR, CHG_TERM_CURR_WORD, CHG_TERM_CURR_OFFSET, 1,
- 100000, 390625, fg_encode_current, NULL),
+ 100000, 390625, 0, fg_encode_current, NULL),
PARAM(DELTA_SOC_THR, DELTA_SOC_THR_WORD, DELTA_SOC_THR_OFFSET, 1, 256,
- 100, fg_encode_default, NULL),
+ 100, 0, fg_encode_default, NULL),
PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_WORD, RECHARGE_SOC_THR_OFFSET,
- 1, 256, 100, fg_encode_default, NULL),
+ 1, 256, 100, 0, fg_encode_default, NULL),
PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD,
- ESR_TIMER_DISCHG_MAX_OFFSET, 2, 1, 1, fg_encode_default, NULL),
+ ESR_TIMER_DISCHG_MAX_OFFSET, 2, 1, 1, 0, fg_encode_default,
+ NULL),
PARAM(ESR_TIMER_DISCHG_INIT, ESR_TIMER_DISCHG_INIT_WORD,
- ESR_TIMER_DISCHG_INIT_OFFSET, 2, 1, 1, fg_encode_default,
+ ESR_TIMER_DISCHG_INIT_OFFSET, 2, 1, 1, 0, fg_encode_default,
NULL),
PARAM(ESR_TIMER_CHG_MAX, ESR_TIMER_CHG_MAX_WORD,
- ESR_TIMER_CHG_MAX_OFFSET, 2, 1, 1, fg_encode_default, NULL),
+ ESR_TIMER_CHG_MAX_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
PARAM(ESR_TIMER_CHG_INIT, ESR_TIMER_CHG_INIT_WORD,
- ESR_TIMER_CHG_INIT_OFFSET, 2, 1, 1, fg_encode_default, NULL),
+ ESR_TIMER_CHG_INIT_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
+};
+
+static struct fg_sram_param pmicobalt_v2_sram_params[] = {
+ PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, 0, NULL,
+ fg_decode_default),
+ PARAM(VOLTAGE_PRED, VOLTAGE_PRED_WORD, VOLTAGE_PRED_OFFSET, 2, 244141,
+ 1000, 0, NULL, fg_decode_value_16b),
+ PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 244141, 1000, 0, NULL,
+ fg_decode_value_16b),
+ PARAM(RSLOW, RSLOW_WORD, RSLOW_OFFSET, 2, 244141, 1000, 0, NULL,
+ fg_decode_value_16b),
+ /* Entries below here are configurable during initialization */
+ PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000,
+ 244141, 0, fg_encode_voltage, NULL),
+ PARAM(EMPTY_VOLT, EMPTY_VOLT_v2_WORD, EMPTY_VOLT_v2_OFFSET, 1, 100000,
+ 390625, -2000, fg_encode_voltage, NULL),
+ PARAM(VBATT_LOW, VBATT_LOW_v2_WORD, VBATT_LOW_v2_OFFSET, 1, 100000,
+ 390625, -2000, fg_encode_voltage, NULL),
+ PARAM(SYS_TERM_CURR, SYS_TERM_CURR_WORD, SYS_TERM_CURR_OFFSET, 3,
+ 1000000, 122070, 0, fg_encode_current, NULL),
+ PARAM(CHG_TERM_CURR, CHG_TERM_CURR_v2_WORD, CHG_TERM_CURR_v2_OFFSET, 1,
+ 100000, 390625, 0, fg_encode_current, NULL),
+ PARAM(DELTA_SOC_THR, DELTA_SOC_THR_v2_WORD, DELTA_SOC_THR_v2_OFFSET, 1,
+ 256, 100, 0, fg_encode_default, NULL),
+ PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_v2_WORD,
+ RECHARGE_SOC_THR_v2_OFFSET, 1, 256, 100, 0, fg_encode_default,
+ NULL),
+ PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD,
+ ESR_TIMER_DISCHG_MAX_OFFSET, 2, 1, 1, 0, fg_encode_default,
+ NULL),
+ PARAM(ESR_TIMER_DISCHG_INIT, ESR_TIMER_DISCHG_INIT_WORD,
+ ESR_TIMER_DISCHG_INIT_OFFSET, 2, 1, 1, 0, fg_encode_default,
+ NULL),
+ PARAM(ESR_TIMER_CHG_MAX, ESR_TIMER_CHG_MAX_WORD,
+ ESR_TIMER_CHG_MAX_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
+ PARAM(ESR_TIMER_CHG_INIT, ESR_TIMER_CHG_INIT_WORD,
+ ESR_TIMER_CHG_INIT_OFFSET, 2, 1, 1, 0, fg_encode_default, NULL),
};
static int fg_gen3_debug_mask;
@@ -336,30 +386,13 @@ static int fg_decode(struct fg_sram_param *sp, enum fg_sram_param_id id,
return sp[id].decode(sp, id, value);
}
-static void fg_encode_voltage_16b(struct fg_sram_param *sp,
- enum fg_sram_param_id id, int val, u8 *buf)
-{
- int i, mask = 0xff;
- int64_t temp;
-
- temp = (int64_t)div_u64((u64)val * sp[id].numrtr, sp[id].denmtr);
- pr_debug("temp: %llx id: %d, val: %d, buf: [ ", temp, id, val);
- for (i = 0; i < sp[id].len; i++) {
- buf[i] = temp & mask;
- temp >>= 8;
- pr_debug("%x ", buf[i]);
- }
- pr_debug("]\n");
-}
-
-static void fg_encode_voltage_8b(struct fg_sram_param *sp,
+static void fg_encode_voltage(struct fg_sram_param *sp,
enum fg_sram_param_id id, int val, u8 *buf)
{
int i, mask = 0xff;
int64_t temp;
- /* Offset is 2.5V */
- val -= 2500;
+ val += sp[id].offset;
temp = (int64_t)div_u64((u64)val * sp[id].numrtr, sp[id].denmtr);
pr_debug("temp: %llx id: %d, val: %d, buf: [ ", temp, id, val);
for (i = 0; i < sp[id].len; i++) {
@@ -430,11 +463,11 @@ static int fg_get_sram_prop(struct fg_chip *chip, enum fg_sram_param_id id,
if (id < 0 || id > FG_SRAM_MAX || chip->sp[id].len > sizeof(buf))
return -EINVAL;
- rc = fg_sram_read(chip, chip->sp[id].address, chip->sp[id].offset,
+ rc = fg_sram_read(chip, chip->sp[id].addr_word, chip->sp[id].addr_byte,
buf, chip->sp[id].len, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error reading address 0x%04x[%d] rc=%d\n",
- chip->sp[id].address, chip->sp[id].offset, rc);
+ chip->sp[id].addr_word, chip->sp[id].addr_byte, rc);
return rc;
}
@@ -740,8 +773,8 @@ static int fg_set_esr_timer(struct fg_chip *chip, int cycles, bool charging,
fg_encode(chip->sp, timer_max, cycles, buf);
rc = fg_sram_write(chip,
- chip->sp[timer_max].address,
- chip->sp[timer_max].offset, buf,
+ chip->sp[timer_max].addr_word,
+ chip->sp[timer_max].addr_byte, buf,
chip->sp[timer_max].len, flags);
if (rc < 0) {
pr_err("Error in writing esr_timer_dischg_max, rc=%d\n",
@@ -751,8 +784,8 @@ static int fg_set_esr_timer(struct fg_chip *chip, int cycles, bool charging,
fg_encode(chip->sp, timer_init, cycles, buf);
rc = fg_sram_write(chip,
- chip->sp[timer_init].address,
- chip->sp[timer_init].offset, buf,
+ chip->sp[timer_init].addr_word,
+ chip->sp[timer_init].addr_byte, buf,
chip->sp[timer_init].len, flags);
if (rc < 0) {
pr_err("Error in writing esr_timer_dischg_init, rc=%d\n",
@@ -882,8 +915,8 @@ static int fg_hw_init(struct fg_chip *chip)
u8 buf[4], val;
fg_encode(chip->sp, FG_SRAM_CUTOFF_VOLT, chip->dt.cutoff_volt_mv, buf);
- rc = fg_sram_write(chip, chip->sp[FG_SRAM_CUTOFF_VOLT].address,
- chip->sp[FG_SRAM_CUTOFF_VOLT].offset, buf,
+ rc = fg_sram_write(chip, chip->sp[FG_SRAM_CUTOFF_VOLT].addr_word,
+ chip->sp[FG_SRAM_CUTOFF_VOLT].addr_byte, buf,
chip->sp[FG_SRAM_CUTOFF_VOLT].len, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing cutoff_volt, rc=%d\n", rc);
@@ -891,8 +924,8 @@ static int fg_hw_init(struct fg_chip *chip)
}
fg_encode(chip->sp, FG_SRAM_EMPTY_VOLT, chip->dt.empty_volt_mv, buf);
- rc = fg_sram_write(chip, chip->sp[FG_SRAM_EMPTY_VOLT].address,
- chip->sp[FG_SRAM_EMPTY_VOLT].offset, buf,
+ rc = fg_sram_write(chip, chip->sp[FG_SRAM_EMPTY_VOLT].addr_word,
+ chip->sp[FG_SRAM_EMPTY_VOLT].addr_byte, buf,
chip->sp[FG_SRAM_EMPTY_VOLT].len, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing empty_volt, rc=%d\n", rc);
@@ -901,8 +934,8 @@ static int fg_hw_init(struct fg_chip *chip)
fg_encode(chip->sp, FG_SRAM_CHG_TERM_CURR, chip->dt.chg_term_curr_ma,
buf);
- rc = fg_sram_write(chip, chip->sp[FG_SRAM_CHG_TERM_CURR].address,
- chip->sp[FG_SRAM_CHG_TERM_CURR].offset, buf,
+ rc = fg_sram_write(chip, chip->sp[FG_SRAM_CHG_TERM_CURR].addr_word,
+ chip->sp[FG_SRAM_CHG_TERM_CURR].addr_byte, buf,
chip->sp[FG_SRAM_CHG_TERM_CURR].len, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing chg_term_curr, rc=%d\n", rc);
@@ -911,8 +944,8 @@ static int fg_hw_init(struct fg_chip *chip)
fg_encode(chip->sp, FG_SRAM_SYS_TERM_CURR, chip->dt.sys_term_curr_ma,
buf);
- rc = fg_sram_write(chip, chip->sp[FG_SRAM_SYS_TERM_CURR].address,
- chip->sp[FG_SRAM_SYS_TERM_CURR].offset, buf,
+ rc = fg_sram_write(chip, chip->sp[FG_SRAM_SYS_TERM_CURR].addr_word,
+ chip->sp[FG_SRAM_SYS_TERM_CURR].addr_byte, buf,
chip->sp[FG_SRAM_SYS_TERM_CURR].len, FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in writing sys_term_curr, rc=%d\n", rc);
@@ -922,8 +955,8 @@ static int fg_hw_init(struct fg_chip *chip)
if (chip->dt.vbatt_low_thr_mv > 0) {
fg_encode(chip->sp, FG_SRAM_VBATT_LOW,
chip->dt.vbatt_low_thr_mv, buf);
- rc = fg_sram_write(chip, chip->sp[FG_SRAM_VBATT_LOW].address,
- chip->sp[FG_SRAM_VBATT_LOW].offset, buf,
+ rc = fg_sram_write(chip, chip->sp[FG_SRAM_VBATT_LOW].addr_word,
+ chip->sp[FG_SRAM_VBATT_LOW].addr_byte, buf,
chip->sp[FG_SRAM_VBATT_LOW].len,
FG_IMA_DEFAULT);
if (rc < 0) {
@@ -936,8 +969,8 @@ static int fg_hw_init(struct fg_chip *chip)
fg_encode(chip->sp, FG_SRAM_DELTA_SOC_THR,
chip->dt.delta_soc_thr, buf);
rc = fg_sram_write(chip,
- chip->sp[FG_SRAM_DELTA_SOC_THR].address,
- chip->sp[FG_SRAM_DELTA_SOC_THR].offset,
+ chip->sp[FG_SRAM_DELTA_SOC_THR].addr_word,
+ chip->sp[FG_SRAM_DELTA_SOC_THR].addr_byte,
buf, chip->sp[FG_SRAM_DELTA_SOC_THR].len,
FG_IMA_DEFAULT);
if (rc < 0) {
@@ -950,8 +983,8 @@ static int fg_hw_init(struct fg_chip *chip)
fg_encode(chip->sp, FG_SRAM_RECHARGE_SOC_THR,
chip->dt.recharge_soc_thr, buf);
rc = fg_sram_write(chip,
- chip->sp[FG_SRAM_RECHARGE_SOC_THR].address,
- chip->sp[FG_SRAM_RECHARGE_SOC_THR].offset,
+ chip->sp[FG_SRAM_RECHARGE_SOC_THR].addr_word,
+ chip->sp[FG_SRAM_RECHARGE_SOC_THR].addr_byte,
buf, chip->sp[FG_SRAM_RECHARGE_SOC_THR].len,
FG_IMA_DEFAULT);
if (rc < 0) {
@@ -1283,6 +1316,8 @@ static int fg_parse_dt(struct fg_chip *chip)
case PMICOBALT_SUBTYPE:
if (chip->pmic_rev_id->rev4 < PMICOBALT_V2P0_REV4)
chip->sp = pmicobalt_v1_sram_params;
+ else if (chip->pmic_rev_id->rev4 == PMICOBALT_V2P0_REV4)
+ chip->sp = pmicobalt_v2_sram_params;
else
return -EINVAL;
break;