power: pm8921-bms: adjust the coulomb counter as per revision
The value of LSB for coulomb counter readings are different for pmic
revisions 2.0 onwards. Adjust the coulomb counter readings for them.
While at it, replace macros with functions to avail of type checking
the compiler provides.
Also since the calculate_cc_mvh() actually returns the cc value
in milli amp hour, rename that function to calculate_cc_mah()
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
diff --git a/drivers/power/pm8921-bms.c b/drivers/power/pm8921-bms.c
index eb98eed..5fd65c6 100644
--- a/drivers/power/pm8921-bms.c
+++ b/drivers/power/pm8921-bms.c
@@ -77,6 +77,7 @@
struct pc_sf_lut *pc_sf_lut;
struct delayed_work calib_work;
unsigned int calib_delay_ms;
+ unsigned int revision;
unsigned int batt_temp_channel;
unsigned int vbat_channel;
unsigned int pmic_bms_irq[PM_BMS_MAX_INTS];
@@ -577,10 +578,41 @@
return pc;
}
-#define CC_TO_MICROVOLT(cc) div_s64(cc * 1085069, 100000);
-#define CCMICROVOLT_TO_UVH(cc_uv) div_s64(cc_uv * 55, 32768 * 3600)
+#define CC_RESOLUTION_N_V1 1085069
+#define CC_RESOLUTION_D_V1 100000
+#define CC_RESOLUTION_N_V2 868056
+#define CC_RESOLUTION_D_V2 10000
+static s64 cc_to_microvolt_v1(s64 cc)
+{
+ return div_s64(cc * CC_RESOLUTION_N_V1, CC_RESOLUTION_D_V1);
+}
-static void calculate_cc_mvh(struct pm8921_bms_chip *chip, int64_t *val,
+static s64 cc_to_microvolt_v2(s64 cc)
+{
+ return div_s64(cc * CC_RESOLUTION_N_V2, CC_RESOLUTION_D_V2);
+}
+
+static s64 cc_to_microvolt(struct pm8921_bms_chip *chip, s64 cc)
+{
+ /*
+ * resolution (the value of a single bit) was changed after revision 2.0
+ * for more accurate readings
+ */
+ return (chip->revision < PM8XXX_REVISION_8901_2p0) ?
+ cc_to_microvolt_v1((s64)cc) :
+ cc_to_microvolt_v2((s64)cc);
+}
+
+#define CC_READING_TICKS 55
+#define SLEEP_CLK_HZ 32768
+#define SECONDS_PER_HOUR 3600
+static s64 ccmicrovolt_to_uvh(s64 cc_uv)
+{
+ return div_s64(cc_uv * CC_READING_TICKS,
+ SLEEP_CLK_HZ * SECONDS_PER_HOUR);
+}
+
+static void calculate_cc_mah(struct pm8921_bms_chip *chip, int64_t *val,
int *coulumb_counter, int *update_userspace)
{
int rc;
@@ -595,9 +627,9 @@
*update_userspace = 0;
}
cc_voltage_uv = (int64_t)*coulumb_counter;
- cc_voltage_uv = CC_TO_MICROVOLT(cc_voltage_uv);
+ cc_voltage_uv = cc_to_microvolt(chip, cc_voltage_uv);
pr_debug("cc_voltage_uv = %lld microvolts\n", cc_voltage_uv);
- cc_uvh = CCMICROVOLT_TO_UVH(cc_voltage_uv);
+ cc_uvh = ccmicrovolt_to_uvh(cc_voltage_uv);
pr_debug("cc_uvh = %lld micro_volt_hour\n", cc_uvh);
cc_mah = div_s64(cc_uvh, chip->r_sense);
*val = cc_mah;
@@ -692,7 +724,7 @@
remaining_charge, ocv, pc);
/* calculate cc milli_volt_hour */
- calculate_cc_mvh(chip, &cc_mah, &coulumb_counter, &update_userspace);
+ calculate_cc_mah(chip, &cc_mah, &coulumb_counter, &update_userspace);
pr_debug("cc_mah = %lldmAh cc = %d\n", cc_mah, coulumb_counter);
/* calculate remaining usable charge */
@@ -1192,6 +1224,7 @@
chip->batt_temp_channel = pdata->bms_cdata.batt_temp_channel;
chip->vbat_channel = pdata->bms_cdata.vbat_channel;
+ chip->revision = pm8xxx_get_revision(chip->dev->parent);
rc = pm8921_bms_hw_init(chip);
if (rc) {