diff options
author | Marcus Cooper <marcus.xm.cooper@stericsson.com> | 2013-01-11 08:12:54 -0500 |
---|---|---|
committer | Anton Vorontsov <anton@enomsg.org> | 2013-01-15 20:43:46 -0500 |
commit | ea4024017831d61874351defe8f8c58ae73f8009 (patch) | |
tree | 0411f756d15ee826c05a603e1218125a0410fcc0 /drivers/power/abx500_chargalg.c | |
parent | a864c5a869dcdb40617fc15166385e0ffa609592 (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.c | 30 |
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: |