- reduce the wait time between adc readings to 20ms from 60ms. This
speeds up the calibration time.
- move the initial calibration to a workqueue.
CRs-Fixed: 331215
Change-Id: I2034c55f2df8d3e1df216dd5a739cbe70e53c2ed
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
There is a bug in the driver where the code to fake full battery
causes coulumb counter based charge (bms_end_cc_uah) to be
reported 0mAh. The reason is once the battery is fully charged a 100% OCV
(open circuit voltage) is faked and columb counter value is offset
such that the coulumb reads start from zero. This faking is cleaned up
until a real OCV happens.
Fix the code such that bms_end_cc_uah is updated before the columb counter
is made to read 0.
Change-Id: I14ce494182ac899205fa41ad815a030d573ab793
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The current code always overwrites last_charger_increase when end
of charging happens. Update the code to add the current percent
increase.
Change-Id: I645554b65de627d26ab01399a6e25a9f5a014fe5
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The coulomb counter in hardware is 32bits and is signed. The software
also adds a 32bit value (the cc reading when end of charge happened).
This addition might cause the value of the coulomb counter to overflow.
Fix it by switching to 64bit values before adding to it.
CRs-Fixed: 328352
Change-Id: Ic8268014fccca00acd03b0693896ab494fe94d87
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Some test teams need to be able to fake certain battery charge percent
values. Update the bms_fake_battery parameter to do that.
Change-Id: I393f8f0f34f717e7ae6facc17eac8b0925ae040a
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Power supply frameworks requires charge units to be in uAh.
Change the driver to use uAh instead of mAh.
Change-Id: I4d3fdc39e4b4104271c417bd36f94a2861149726
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
When charging starts from very low voltages start_percent will be
calculated as zero. Zero value for start_percent is also used as
a flag to indicate the device did not start charging.
This further causes soc reporting zero value all the time.
Fix this by setting the start_percent and end_percent to -EINVAL when
charging has not started.
Change-Id: I88f8861828b5d8929a5eda04ac9726404a1559c2
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The driver uses 97.7mV as the value of a single bit for calibration
channels. It should however use 97.656mV for these channels.
These fixes a few mV error seen in OCV(open circuit voltage) readings.
Also, remove the sanity checks that forces voltage to be in a certain
range. Forcing voltage on calibration channels could cause errors in
battery voltage reporting.
Change-Id: I21cc665a1b11597692968d4c96ba7f838402c74f
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
There is an issue where the real state of charge is reported
even when the fake battery parameter is set.
Fix it by checking this parameter just before returning the
state of charge value.
Change-Id: I3840373a6b52011c165baa79dc8d096a3533b358
Signed-off-by: Patrick Cain <pcain@codeaurora.org> rFu
Modify the scaling function routines for Battery temperature
and all channels whose units return milli-volts for voltage.
The Charger driver requires the Units of Voltage and temperature
in uV and 0.1 DegC according to the framework where all voltages,
currents, chargers, energies, time and temperature are in uV, uA,
uAh, uWh, seconds and tenths of degree Celsius unless otherwise
stated. In accordance with the above expected units, the scaling
functions are modified for all voltage channels and the Batt Therm.
This change fixes the XO Therm temperature scaling routine,
PA Therm and Batt id to use the ratiometric calibration.
XO Therm and PA therm units are returned as milli-degree and
degree Centigrade respectively.
Accordingly, update the clients of xoadc to handle this change in
units.
CRs-Fixed: 315797
Change-Id: I6fa3b808062563fef3b0e70cc694e3132421f735
Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The userspace needs to know percent, open circuit voltage and columb
based charge properties at the start and end of charging. These values
are essential in calculating the charge delta and possibly generating
an error indication to the user if the battery doesn't hold enough
charge.
CRs-Fixed: 320216
Change-Id: Ida66a62ae9806a7d12b70914d4875ee75d140e5f
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
- the spin_lock only needs to be held while reading from the BMS hardware,
the current code holds it for reading and calculating values from it. Fix
this by creating a function to read values and hold the spinlock around it.
The values are read in a structure which is passed around for further
calculations
- as a result of above change the read_xxxx functions reduce to
convert_xxxx functions. They now convert the raw values to physical
units and don't read it from hardware directly.
- there was a logical and for checking the oreg_hold bit. It should be a
bitwise and.
- since the driver is reading the soc parameters only at one place
with the OREG_HOLD bit set remove the check for oreg_hold while
reading individual parameters
Change-Id: I206d116b2a68fc31d027607d3542a5ac6b5b4439
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
When an end of charge with a full battery happens, the bms driver
fakes max ocv and zero cc. To force max ocv the driver currently
assumes that the first row last column will have the highest profiled
voltage. This may not be true always.
Pass the maximum voltage from platform data and use that to force
max ocv.
Change-Id: I29c71a20648fb2f9066f2f82e14a6080692c63fd
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
An issue was observed when the calculated (real fcc) fcc was very low
as compared to fcc. Usually the fcc should not drop/increase beyond 3%
per charge cycle.
Update the code to check the delta between calculated fcc and the previous
fcc and update the real fcc if delta is within 3 percent.
Change-Id: Ib3ab383971fbd86af91c642ac5a2a38cbb555d9f
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Provide ability to tell the bms that a device is running on a fake
battery. When told so, the bms will calculate the state of charge
as usual but will always report 53% charge left in the battery.
This helps avoiding shutdowns when the percent charge gets very low
- the charge drawn from the fake battery is equal or greater than
the capacity of the battery.
Change-Id: Iabf32adbb0106bde5985dfd6de6517303b5d1922
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Until now only the BMS system was using the ccadc so there was
no need to create a separate ccadc driver.
However we can run in a configuration with BMS disabled
and clients won't be able to read battery current via ccadc.
Separate the ccadc from the bms, this change in is preparation
to add a ccadc api to read the battery current.
Change-Id: Ib96b146d91d01d196df9291eb23432cd430db4d0
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The remaining usable charge is calculated as below
RUC = RC - CC - UUC
RC is the remaining charge when an OCV (open circuit voltage) is
measured by the bms hw. It is some percent of full charge capacity.
The BMS hw continuously monitors the battery current and when it is
low enough it reads the battery voltage and calls it OCV.
CC is the charge based on coulomb counter and represents the
absolute charge provided since an OCV was taken. When OCV happens,
the coulomb counter is reset to zero.
UUC is the unusable charge that the system cannot use because of
internal battery resistance. For the most part this value remains
constant, it changes slowly as the battery ages.
The state of charge (SOC) is calculated as below
SOC = RUC / (FCC - UUC)
When an end of charging event happens, the driver calculates (RC - CC)
and sets that as the new full charge capacity (FCC). However since the
system uses the old OCV value which translates to some percent of full
charge capacity, the soc calculated after this FCC adjustment will be
less than 100%.
To workaround this problem, the software needs to behave as if the
OCV had just happened after charging finishes. IOW force OCV to max
possible value which translates to 100% FCC and force CC to zero.
Substituting RC = 100% FCC = FCC and CC = 0
we get
RUC = FCC - UUC
and
SOC = (FCC - UUC)/ (FCC - UUC)
which is 100%
As the battery now discharges the CC part of the RUC increases lowering
the SOC.
To force CC to zero the driver notes the CC readings when end of charge
happens (cc_reading_at_100) and subtracts this reading for all subsequent
cc reads.
To force an OCV that will translate to 100% FCC the driver uses the
lookup table and picks the highest profiled OCV. This happens to be the
first row and the last column in the profile table.
This software faking the OCV to 100% FCC and CC to zero needs to cease
when a new OCV measurement is taken by the BMS hw. The driver remembers
the old OCV in ocv_reading_at_100 and knows a new OCV is taken if a
different OCV reading is read. It sets the cc_reading_at_100 and
ocv_reading_at_100 to zero.
Note that the system will never read zero as the ocv, a zero OCV
translate to a -ve 2.3986 volt battery voltage - a physical impossibility.
Change-Id: Icfef5b6242185009af7ae443088f86c230ccbe64
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The scaling factor tables are based on aging of the battery. Sometimes
this data wont be available and these tables will be set to null.
Return 100% scaling factor when scaling factor table is missing.
Change-Id: I730813136d7c9fc10892a29f38449df19b5087a3
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Prevent the bms from reporting a higher state of charge (SOC)
without charging. Use the start_percent as an indicator whether
the battery was charged.
Change-Id: Ibd664a3b6fc0f8edc2a99b5bed285465b86dc3c4
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The bms driver calibrates the ccadc channel every few minutes
for offset and gain.
The offset value calibrated needs to be written to the bms hardware
which it uses to adjust all the ccadc readings.
The software has to only adjust for gain for ccadc based readings.
One is not supposed to program the trim offset values in while a
bms conversion in progress. Update the code to try only two times
instead of 10 to check if the conversion is finished, if not enable
the ccadc eoc interrupt and write the values then.
Change-Id: I1a1a16feb5ffb927f630850f0f2539ad75805fb1
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The ccadc needs to be calibrated every few minutes for accurate
battery charge estimation. The output of the calibration procedure
is gain and offset. The gain is used by the software while
the offset is programmed in a trim register. These trim values are
offset by bms every time it does an auto vsense read.
Change-Id: I20f6a7173321aa68967803d67c9a4813bcd75fae
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The procedure to calculate the battery voltage from xoadc raw readings
needs to be updated. Currently the driver multiplies the readings by 3
before calibration. This step needs to be done after calibration.
Also update all battery voltage based read_xxxx functions to
return the calibrated value.
Additionally call the hkadc calibration function at probe time
so early readings of battery voltage will be accurate.
Change-Id: I19c4ae8f124f3442ddffd651445db529ceac1cfe
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
When charging finishes with a full battery, the bms driver calculates
last_real_fcc. This parameter will be preserved between reboots.
Also the battery temperature when last_real_fcc is saved and
preserved between reboots along with last_real_fcc.
Since we are creating additional parameters whose set functions are
different from the others, move all of them to use module param with
accessor functions. Create macros to easily define accessor functions.
While at it change last_rbatt, last_ocv_uv parameters to be updated
only when a valid reading is available from the hardware or when the
userspace programs a new value.
When userspace updates the last_real_fcc and last_real_fcc_batt_temp
we create another adjusted table similar to fcc vs temperature filling up
its entries based on last_real_fcc and last_real_fcc_batt_temp. Note
that the ratios between FCCs at various temperatures are kept the same.
This new adjusted fcc vs temperature table reflects the fcc of the battery
more accurately and the algorithm is updated to use this table when
available. The scalingfactor is not used along with this adjusted table.
Change-Id: Ic1befd07b17fa16889e593fdec51021be4eeb1d5
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The BMS hardware has two sets of registers, shadow registers
which the hardware automatically updates and the output registers
which the software is supposed to read from.
Unless the bms output is locked, the output registers are updated
whenever the shadow registers are updated. If the software were
reading the output registers at the same time, corrupt values
will be read. Moreover the software expects the values to remain
intact while it is doing soc calculations - It reads multiple
registers like ocv, rbatt and cc for one soc calculations and
expects that these registers don't change.
The BMS hardware provides a bit (HOLD_OREG_DATA) where an update to
shadow register won't change the output registers. Set this bit before
reading from the BMS.
Change-Id: Icddf115054b72155479295ba5f4adb3a21b5a97a
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
When the state of charge (SOC) falls below 10% make sure that the
battery voltage too has fallen. If the battery voltage stays high
it means that the device is powered using a fake battery/power
supply.
Report a default soc to the userspace to avoid shutdowns due to a
low SOC.
CRs-Fixed: 309411
Change-Id: Ibd5e76cf7ed926722290840140fde4c592700eba
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
It is good to dump the battery state of charge at bootup, this will help
us debugging low battery issues.
Also dump more debug information when the state of charge readings are bad.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
'row1' and 'row2' might be used uninitialized in
interpolate_scalingfactor_pc.
There would be a memory leak in the probe function if battery
data is bad. Free the chip memory before returning.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
real_fcc is the remaining capacity in the battery when the charger
driver indicates that the battery is fully charged. This value needs
to be calculated when charging ends with a fully charged battery.
The userspace can read this value via module parameter and preserve it
between restarts.
The real reason for calculating this is to indicate how much the battery
capacity has dropped w.r.t the profiled battery data use this deviation
in calculations.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
-Add sysfs interface to read PM8921 HK/XOADC
and thermistor temperature measurements mapped
through MPP's.
-Move PM8921 ADC from directory /drivers/mfd to
/drivers/hwmon for userspace clients to read ADC
through hwmon.
CRs-Fixed: 302365
Signed-off-by: Siddartha Mohanadoss <smohanad@codeaurora.org>
Conflicts:
drivers/mfd/Kconfig
Since the BMS can calculate FCC based on the charge cycles and age, use it
to report ENERGY_FULL property in the power supply framework.
CRs-Fixed: 304029
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Currently the battery data is passed via the board file. Instead
read the battery id and choose the appropriate battery data to use.
CRs-Fixed: 304376
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Arithmetic conversion rules states that a signed operand is converted
to unsigned if the other operand is unsigned.
The voltage across vsense is a signed int and it can be negative.
Dividing it by the battery sense resistor, an unsigned int, was
resulting in a very large positive number instead of a negative number.
Fix it by casting the battery sense resistor to signed so that a
a signed division is performed.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The output of hkadc calibration steps are voltages measured at
0.625V and 1.25V. We use these to adjust the vbatt readings.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The constants used in the calculation to convert vbatt raw readings
to microvolts are incorrect. All vbat readings go through a 1/3rd scaling
before going to xoadc. IOW the xoadc reads 1/3rd of vbatt.
Fix the constants to account for it.
While at it, convert to using a function instead of a macro - to avail
of automatic type checking from the compiler.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
On older pmic versions an ocv (open circuit voltage) may not be
taken at power on time. However the coulomb counter values will
be incremented.
The state of charge calibration is calculated based on ocv and
coulomb counter, so it is essential to get an ocv reading very
early.
If an ocv reading is not available at probe time, calculate it based
on adc readings and the current flow.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Refator the code by creating separate functions for remaining charge
and the unusable charge calulations
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
There are parameters that need not be preserved between reboots.
Delete them and clean up all the code that writes to them.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The pm8921 bms driver can provide instantaneous current. Use the
current now property of the power_supply class to expose this
feature.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Since the vsense readings are done from ccadc, use the conversion
based on cc_to_microvolt for all vsense readings.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
The current algorithm compares if an ocv is between two temperature
columns of the same row. This is not valid since the data in one
temperature column is collected independently of the data in another
temperature column.
It is incorrect to assume a relation between ocv values for the same
percent row for different temeperature columns.
Fix it by finding a percent charge for a bounding temperatures and
then interpolating these percent charges based on battery temperature.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
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>
The Rsense resistor connects between the -ve end of the battery
and GND. The voltage across the Rsense gives us a good indication
of the current flowing through the battery.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
In the interpolate_single_lut print the name of the table when values
are out of bounds.
Change the important values to be printed in capitals in
calculate_state_of_charge functions.
dev_dbg does not follow the pr_fmt. Change to use pr_debug.
Change pr_err to pr_debug for places where the software takes corrective
action.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
Read the battery temeperature and voltage from the adc driver instead
of hard coding them in the driver.
In the charing began and charing end functions, use
pm8921_bms_get_percent_charge api. This prevents duplicating calling
the adc functions.
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>