qcom-charger: fg-util: add float decode function
Some SRAM registers are encoded using a floating point representation.
Add a function to decode these registers into signed micro-unit
integers.
The exponent and mantissa are signed integers represented by two's
complement, and the exponent value is offset by -9. This is a half
float representation stored as:
EEEEE MMMMMMMMMMM
Where E are the exponent bits, and M are the mantissa bits.
To decode this representation the following formula is applied:
2^(exponent - 9) * mantissa
Change-Id: Id9f28a0eeb2a904aca41eb46d0215d80287e0b88
Signed-off-by: Nicholas Troast <ntroast@codeaurora.org>
diff --git a/drivers/power/qcom-charger/fg-core.h b/drivers/power/qcom-charger/fg-core.h
index 08ec733..a609d8f 100644
--- a/drivers/power/qcom-charger/fg-core.h
+++ b/drivers/power/qcom-charger/fg-core.h
@@ -252,4 +252,5 @@
extern int fg_sram_debugfs_create(struct fg_chip *chip);
extern void fill_string(char *str, size_t str_len, u8 *buf, int buf_len);
extern int64_t twos_compliment_extend(int64_t val, int s_bit_pos);
+extern s64 fg_float_decode(u16 val);
#endif
diff --git a/drivers/power/qcom-charger/fg-util.c b/drivers/power/qcom-charger/fg-util.c
index 609a3ff..b30b880 100644
--- a/drivers/power/qcom-charger/fg-util.c
+++ b/drivers/power/qcom-charger/fg-util.c
@@ -29,6 +29,26 @@
},
};
+#define EXPONENT_SHIFT 11
+#define EXPONENT_OFFSET -9
+#define MANTISSA_SIGN_BIT 10
+#define MICRO_UNIT 1000000
+s64 fg_float_decode(u16 val)
+{
+ s8 exponent;
+ s32 mantissa;
+
+ /* mantissa bits are shifted out during sign extension */
+ exponent = ((s16)val >> EXPONENT_SHIFT) + EXPONENT_OFFSET;
+ /* exponent bits are shifted out during sign extension */
+ mantissa = sign_extend32(val, MANTISSA_SIGN_BIT) * MICRO_UNIT;
+
+ if (exponent < 0)
+ return (s64)mantissa >> -exponent;
+
+ return (s64)mantissa << exponent;
+}
+
void fill_string(char *str, size_t str_len, u8 *buf, int buf_len)
{
int pos = 0;