power: pm8921-bms: fine tune the uuc scaling algorithm

For every soc calculations there are three unusable charge (uuc)
values.
uuc_uah_itest:
	The uuc value in micro amp hour (uah) based on the max current
	(itest). Typically this value is very high and changes as the
	battery resistance changes
uuc_uah_iavg:
	The uuc value based on the average current (iavg). Typically
	this is lower than uuc_itest
uuc_reported:
	The reported uuc based on state of charge (SOC) of the battery
	which chooses a stepsize value and approaches towards
	uuc_uah_itest or uuc_uah_iavg based on whether the device is
	being charged.

The expectation is that the reported uuc increase as the battery looses SOC
and decrease as SOC approaches full condition.

To help us coming up with a satisfactory algorithm the following
parameters are introduced.
uuc_multiplier:
	The multiplier used in stepsize calculation
uuc_iavg_div:
	The divisor to use in calculation of stepsize when there
	is a significant jump in average current from the
	previous attempt
uuc_min_step_size:
	The minimum stepsize to use if the calculated stepsize is very less

Also, in order to ignore the high bootup time load a timer is introduced
which makes the algorithm ignore iavg values upon bootup.

The algorithm also uses the previous uuc based on iavg in
"uuc_uah_iavg_prev". This aids in checking if there was a significant
increase in average current from the previous time uuc was calculated.
The algorithm keeps track of the previous reported uuc in last_uuc_uah.

Change-Id: I360fd74e7fd2c939dd67023c128b2d70da923e9a
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-charger: change BOOT_DONE configuration

Set the BOOT_TIMER_EN bit when writing the
BOOT_DONE configuration. This is required to make
sure the boot timer will be enabled during the
next phone boot.

Change-Id: I0c43de3a0c285979f7bccd42e464ca0d2fbbe42a
Signed-off-by: David Keitel <dkeitel@codeaurora.org>
power: pm8921-charger: add UVD threshold API

PM8917 has a new register which allows configuring
the falling USB under voltage detection (UVD) threshold
from 3.85V to 4.35V in 100 mV steps.

Add an API that allows to set this value per default and
also only do this for PM8917 chips.

Change-Id: I9b4259b43f148762ac72af40bdc79b895d9b4fc2
Signed-off-by: David Keitel <dkeitel@codeaurora.org>
power: pm8921-charger: add reverse boost fix for dc_in

Reverse boosting is also seen on the DC charging path
and may cause charger removal detection problems.

Fix this by changing the reverse boost detection to only
check the active charging path. Only the active charging
path will see reverse boosting voltages because the other
path's OVP will automatically be opened (off) by the
hardware.

Change-Id: I23a48cd49d912e2bb2651159ec91d0ccfa7f5e0d
Signed-off-by: David Keitel <dkeitel@codeaurora.org>
power: pm8921-charger: add dc_unplug_check option

Add a configuration option to enable or disable
the reverse boost fix for the DC charging path.

Some board designs do not utilize the DC_IN path
on the PMIC, however they do use the presence
detection of DC_IN to enable the auto switching
and interrupt features. In these particular configurations
the PMIC does not control the DC OVP FETs.
Hence add an option to enable or disable the DC path workaround
and leave the workaround disabled by default.

Change-Id: I1e55bbfe37c7cc6f62581af11280a565ed648c06
Signed-off-by: David Keitel <dkeitel@codeaurora.org>
power: power_supply_core: add power_supply_set_supply_type API

Allow other drivers to change the supply type of a given power
supply. This is required when a USB driver determines the exact
USB connection type and needs to notify the owner of the usb power
supply struct.

Change-Id: I99d377628a296704e1dcd170251ab9ceadc653ec
Signed-off-by: David Keitel <dkeitel@codeaurora.org>
power: pm8921-bms: dont use override mode if batfet is open

If the battery fet is open, the current sourced or sinked from the
battery is very low. There is a high chance that an open circuit
voltage(OCV) happens. Putting the BMS in override mode resets the timer
whose expiry causes an OCV.

Avoid putting the BMS in override mode if battery fet is open.

Change-Id: Idc463bcc55b51cf188cc8ee440a66f763654f174
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: remove reading rbatt from bms

Since battery resistance is found to be changing w.r.t. state of charge,
temperature and time since a load change happened, it is best if rbatt
is estimated using learnt tables.

Remove all the code that attempts to read battery resistance from BMS.

Change-Id: Id8d84d610df0bcca79d7e42ffae572c0898d63c6
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: fix rounding down state of charge

The code is rounding down state of charge value in the final step of the
calculation. Instead use a division that returns the closest integer.

Change-Id: Ia47d1c4eb684dd4c31e454dc762add0feab66b75
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8xxx-ccadc: missing calibration at bootup

There is a bug in the sequence between when the calibration work is
scheduled and the global chip pointer is initialized. If work is
scheduled before the chip pointer is initialized it refuses to
calibrate.

Initialize the chip pointer before scheduling calibration work.

Change-Id: I333c97c005e8bc17a28fc0dac3f76e4f26fcc486
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: periodic hkadc calibration

Introduce periodic hkadc calibration again. A bug was introduced when
periodic ccadc calibration code was moved to the ccadc driver - hkadc
calibration got dropped.

Reintroduce periodic hkadc calibration.

Change-Id: Ib22e03ce881320ca556bfbddd55e658b42363065
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: use direct charger api instead of power supply api

The power supply api reports usb as missing if a usb wall charger
is plugged in - this is expected as a usb wall charger should be
treated as a dc charger - not a usb charger.

The bms needs to know if anything is connected to the usb port, it
does not care whether it is a usb wall charger or pc usb charger.

Use a direct api exposed by the charger that reports the USBIN_VALID
bit.

Change-Id: Ide05f7da1b14ad3b288633e887611dd5fa79276a
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: use shutdown_soc to force power on soc

Experiments have shown that shutdown_soc is very accurate. However
upon a restart, the battery may be unsettled, leading to a significantly
different power on soc.

Update the code to force the value of shutdown soc on the power on
soc. To do this simply update the power on OCV (open circuit voltage)
value.

Change-Id: I1015b800e559cb08422364ffc8c8b981ddd4f07e
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: remove Dynamic Unusable Charge algorithm

The dynamic UUC algorithm changes the UUC as load, state of charge and
temperature changes. This uncontrolled behaviour causes unacceptable
jumps in state of charge numbers.

Replace the dynamic UUC algorithm with a simple average current based
UUC. The average current is calculated by remembering the load for last
few (16) samples. Also to maintain a reasonable UUC while charging, a
load of 300mA is assumed.

Note that the first time UUC is calculated we don't have load samples
and in that case the instantaneous current is used.

Since we now don't change the UUC with respect to max possible load
(itest), the usage of this value is removed.  Also instead of failure
voltage we introduce cutoff voltage which represents the loaded voltage
by which the battery should be reported 0%.

Change-Id: Ia640164ee2c9690537308d4e840953824ba15b58
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: increase soc slowly while charging

It could happen that the calculated soc was higher than the reported
soc even when a charger is not plugged in. This usually happens when
the battery temperature increases or the average current changes causing
unusable charge to go low. The current code never reports this high soc
unless a charger is plugged in.

However at the instant when charger is plugged in, the driver reports
that high calculated soc. This jump in soc in an instant is
unacceptable.

Slowly increase the reported soc so that it approaches the calculated
soc while charging. Basically we are playing catchup between reported
soc and calculated soc. The catch up time is based on how big the
difference between calculated soc and reported soc is - we allow
60 seconds per percent delta.

Change-Id: Ic1ae741c23ea596a46ca2cd49b58c75cf773c3e5
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-charger: increase hearbeat if battery is low

When the battery percent charge goes low we want to increase the
frequency of state of charge updates. This helps the correction
algorithm ample opportunities to correct the state of charge and
prevent a low voltage shutdown.

Change-Id: Ie846350ee4c1fd70198d28646779b20349134ef7
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: adjust rbatt and ocv both for shutdown soc

When ocv (open circuit voltage of the battery) is adjusted to match a
specific soc, rbatt (the battery resistance) changes too. This is because
rbatt is dependent on the remaining charge which changes as the ocv
changes.

The issue we observed with this changing rbatt was the unusable charge
changes which causes the soc to move away from the soc the algorithm
attempts to match.

To get around this issue adjust both the rbatt and ocv when we want to
match a soc for a specific soc.

Change-Id: Ifa8efe1e37b9982d6d67730f911e47e369e9b4ff
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: use background work to calculate soc

The soc (state of charge) calculation algorithms and the associated
adjusting algorithms were coded assuming that the soc will be queried
at distant intervals (more than 20 seconds).

However this assumption is bad and soc can be queried at sub second
intervals. These soc queries in quick succession causes the adjusting
algorithm to over correct the battery voltage.

Separate the soc calculation from the soc reporting - calculate soc
at specific intervals, while the reporting uses the values resulting
from the latest calculation. This way the adjusting algorithms run
at specified intervals and are not perturbed by the sub second querying
for soc.

Change-Id: I240bfdbd3ae3b2e37ae16cc3757a25f5a918e972
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: iterate rbatt algorithm

When ocv (open circuit voltage of the battery) is adjusted to match a
specific soc, rbatt (the battery resistance) changes too. This is
because rbatt is dependent on the remaining charge which changes as
the ocv changes.

The issue we observed with this changing rbatt was the unusable charge
changes which causes the soc to move away from the soc the algorithm
attempts to match.

To get around this issue adjust both the rbatt and ocv in a iterative
fashion until rbatt value stabilizes.

Change-Id: Id3e36c1a8361a6d71b63fca3e6b0c2a4a9bb7e06
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
power: pm8921-bms: dont adjust at high battery capacity

The adjusting algorithm was designed to prevent uvlo event towards
low state of charge situations. It works by decreasing ocv so that the
a lower soc is reported.

When the battery is fully charged, we fake an ocv event, causing the
ocv to jump to 100% and cc to 0. But after a few milliseconds when
charging stops, the adjusting algorithm reduces the ocv which
causes the SOC to jump from 100% to 99%.

This jump from 100 to 99 is incorrect. Moreover we have seen quick
decreases at high soc range because of the adjusting algorithm.
To fix that and the 100 to 99% jumps simply don't run the adjusting
algorithm when the battery soc is above 90%.

Change-Id: I68e8bb72ec0e58552f9fedecceaffbf149c1f10e
Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>