aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/abx500_chargalg.c
diff options
context:
space:
mode:
authorMarcus Cooper <marcus.xm.cooper@stericsson.com>2013-01-11 08:12:54 -0500
committerAnton Vorontsov <anton@enomsg.org>2013-01-15 20:43:46 -0500
commitea4024017831d61874351defe8f8c58ae73f8009 (patch)
tree0411f756d15ee826c05a603e1218125a0410fcc0 /drivers/power/abx500_chargalg.c
parenta864c5a869dcdb40617fc15166385e0ffa609592 (diff)
ab8500_bm: Recharge condition not optimal for battery
Today the battery recharge is determined with a voltage threshold. This voltage threshold is only valid when the battery is relaxed. In charging algorithm the voltage read is the loaded battery voltage and no compensation is done to get the relaxed voltage. When maintenance charging is not selected, this makes the recharging condition to almost immediately activate when there is a discharge present on the battery. Depending on which vendor the battery comes from this behavior can wear out the battery much faster than normal. The fuelgauge driver is responsible to monitor the actual battery capacity and is able to estimate the remaining capacity. It is better to use the remaining capacity as a limit to determine when battery should be recharged. Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Marcus Cooper <marcus.xm.cooper@stericsson.com> Reviewed-by: Hakan BERG <hakan.berg@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com> Signed-off-by: Anton Vorontsov <anton@enomsg.org>
Diffstat (limited to 'drivers/power/abx500_chargalg.c')
-rw-r--r--drivers/power/abx500_chargalg.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c
index 8b69da0ae5af..78b623572b52 100644
--- a/drivers/power/abx500_chargalg.c
+++ b/drivers/power/abx500_chargalg.c
@@ -33,9 +33,6 @@
33/* End-of-charge criteria counter */ 33/* End-of-charge criteria counter */
34#define EOC_COND_CNT 10 34#define EOC_COND_CNT 10
35 35
36/* Recharge criteria counter */
37#define RCH_COND_CNT 3
38
39#define to_abx500_chargalg_device_info(x) container_of((x), \ 36#define to_abx500_chargalg_device_info(x) container_of((x), \
40 struct abx500_chargalg, chargalg_psy); 37 struct abx500_chargalg, chargalg_psy);
41 38
@@ -196,7 +193,6 @@ enum maxim_ret {
196 * @dev: pointer to the structure device 193 * @dev: pointer to the structure device
197 * @charge_status: battery operating status 194 * @charge_status: battery operating status
198 * @eoc_cnt: counter used to determine end-of_charge 195 * @eoc_cnt: counter used to determine end-of_charge
199 * @rch_cnt: counter used to determine start of recharge
200 * @maintenance_chg: indicate if maintenance charge is active 196 * @maintenance_chg: indicate if maintenance charge is active
201 * @t_hyst_norm temperature hysteresis when the temperature has been 197 * @t_hyst_norm temperature hysteresis when the temperature has been
202 * over or under normal limits 198 * over or under normal limits
@@ -223,7 +219,6 @@ struct abx500_chargalg {
223 struct device *dev; 219 struct device *dev;
224 int charge_status; 220 int charge_status;
225 int eoc_cnt; 221 int eoc_cnt;
226 int rch_cnt;
227 bool maintenance_chg; 222 bool maintenance_chg;
228 int t_hyst_norm; 223 int t_hyst_norm;
229 int t_hyst_lowhigh; 224 int t_hyst_lowhigh;
@@ -858,6 +853,7 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data)
858 union power_supply_propval ret; 853 union power_supply_propval ret;
859 int i, j; 854 int i, j;
860 bool psy_found = false; 855 bool psy_found = false;
856 bool capacity_updated = false;
861 857
862 psy = (struct power_supply *)data; 858 psy = (struct power_supply *)data;
863 ext = dev_get_drvdata(dev); 859 ext = dev_get_drvdata(dev);
@@ -870,6 +866,16 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data)
870 if (!psy_found) 866 if (!psy_found)
871 return 0; 867 return 0;
872 868
869 /*
870 * If external is not registering 'POWER_SUPPLY_PROP_CAPACITY' to its
871 * property because of handling that sysfs entry on its own, this is
872 * the place to get the battery capacity.
873 */
874 if (!ext->get_property(ext, POWER_SUPPLY_PROP_CAPACITY, &ret)) {
875 di->batt_data.percent = ret.intval;
876 capacity_updated = true;
877 }
878
873 /* Go through all properties for the psy */ 879 /* Go through all properties for the psy */
874 for (j = 0; j < ext->num_properties; j++) { 880 for (j = 0; j < ext->num_properties; j++) {
875 enum power_supply_property prop; 881 enum power_supply_property prop;
@@ -1154,7 +1160,8 @@ static int abx500_chargalg_get_ext_psy_data(struct device *dev, void *data)
1154 } 1160 }
1155 break; 1161 break;
1156 case POWER_SUPPLY_PROP_CAPACITY: 1162 case POWER_SUPPLY_PROP_CAPACITY:
1157 di->batt_data.percent = ret.intval; 1163 if (!capacity_updated)
1164 di->batt_data.percent = ret.intval;
1158 break; 1165 break;
1159 default: 1166 default:
1160 break; 1167 break;
@@ -1424,16 +1431,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
1424 case STATE_WAIT_FOR_RECHARGE_INIT: 1431 case STATE_WAIT_FOR_RECHARGE_INIT:
1425 abx500_chargalg_hold_charging(di); 1432 abx500_chargalg_hold_charging(di);
1426 abx500_chargalg_state_to(di, STATE_WAIT_FOR_RECHARGE); 1433 abx500_chargalg_state_to(di, STATE_WAIT_FOR_RECHARGE);
1427 di->rch_cnt = RCH_COND_CNT;
1428 /* Intentional fallthrough */ 1434 /* Intentional fallthrough */
1429 1435
1430 case STATE_WAIT_FOR_RECHARGE: 1436 case STATE_WAIT_FOR_RECHARGE:
1431 if (di->batt_data.volt <= 1437 if (di->batt_data.percent <=
1432 di->bm->bat_type[di->bm->batt_id].recharge_vol) { 1438 di->bm->bat_type[di->bm->batt_id].
1433 if (di->rch_cnt-- == 0) 1439 recharge_cap)
1434 abx500_chargalg_state_to(di, STATE_NORMAL_INIT); 1440 abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
1435 } else
1436 di->rch_cnt = RCH_COND_CNT;
1437 break; 1441 break;
1438 1442
1439 case STATE_MAINTENANCE_A_INIT: 1443 case STATE_MAINTENANCE_A_INIT: