aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power/apm_power.c
diff options
context:
space:
mode:
authorAnton Vorontsov <cbou@mail.ru>2007-10-04 17:05:00 -0400
committerAnton Vorontsov <cbou@mail.ru>2007-10-04 17:05:00 -0400
commit2a721dfc8c677588fc98d818dfad3354081c6ddb (patch)
tree93a4b90d68e3b445adc57333df07369c1c97b7af /drivers/power/apm_power.c
parentd385376f0d75fdbeed8041ed6baf5cb4a1578ffb (diff)
apm_power: calculate to_full/to_empty time using energy
This patch adds ability to calculate time using energy. Needed to calculate time_to_full for PMU batteries. Signed-off-by: Anton Vorontsov <cbou@mail.ru>
Diffstat (limited to 'drivers/power/apm_power.c')
-rw-r--r--drivers/power/apm_power.c78
1 files changed, 53 insertions, 25 deletions
diff --git a/drivers/power/apm_power.c b/drivers/power/apm_power.c
index 3928e7cdddc1..bbf3ee10da04 100644
--- a/drivers/power/apm_power.c
+++ b/drivers/power/apm_power.c
@@ -87,41 +87,63 @@ static void find_main_battery(void)
87 } 87 }
88} 88}
89 89
90static int calculate_time(int status) 90static int calculate_time(int status, int using_charge)
91{ 91{
92 union power_supply_propval charge_full, charge_empty; 92 union power_supply_propval full;
93 union power_supply_propval charge, I; 93 union power_supply_propval empty;
94 union power_supply_propval cur;
95 union power_supply_propval I;
96 enum power_supply_property full_prop;
97 enum power_supply_property full_design_prop;
98 enum power_supply_property empty_prop;
99 enum power_supply_property empty_design_prop;
100 enum power_supply_property cur_avg_prop;
101 enum power_supply_property cur_now_prop;
94 102
95 if (MPSY_PROP(CHARGE_FULL, &charge_full)) { 103 if (MPSY_PROP(CURRENT_AVG, &I)) {
96 /* if battery can't report this property, use design value */ 104 /* if battery can't report average value, use momentary */
97 if (MPSY_PROP(CHARGE_FULL_DESIGN, &charge_full)) 105 if (MPSY_PROP(CURRENT_NOW, &I))
98 return -1; 106 return -1;
99 } 107 }
100 108
101 if (MPSY_PROP(CHARGE_EMPTY, &charge_empty)) { 109 if (using_charge) {
102 /* if battery can't report this property, use design value */ 110 full_prop = POWER_SUPPLY_PROP_CHARGE_FULL;
103 if (MPSY_PROP(CHARGE_EMPTY_DESIGN, &charge_empty)) 111 full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN;
104 charge_empty.intval = 0; 112 empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
113 empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
114 cur_avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG;
115 cur_now_prop = POWER_SUPPLY_PROP_CHARGE_NOW;
116 } else {
117 full_prop = POWER_SUPPLY_PROP_ENERGY_FULL;
118 full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN;
119 empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY;
120 empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY;
121 cur_avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG;
122 cur_now_prop = POWER_SUPPLY_PROP_ENERGY_NOW;
105 } 123 }
106 124
107 if (MPSY_PROP(CHARGE_AVG, &charge)) { 125 if (_MPSY_PROP(full_prop, &full)) {
108 /* if battery can't report average value, use momentary */ 126 /* if battery can't report this property, use design value */
109 if (MPSY_PROP(CHARGE_NOW, &charge)) 127 if (_MPSY_PROP(full_design_prop, &full))
110 return -1; 128 return -1;
111 } 129 }
112 130
113 if (MPSY_PROP(CURRENT_AVG, &I)) { 131 if (_MPSY_PROP(empty_prop, &empty)) {
132 /* if battery can't report this property, use design value */
133 if (_MPSY_PROP(empty_design_prop, &empty))
134 empty.intval = 0;
135 }
136
137 if (_MPSY_PROP(cur_avg_prop, &cur)) {
114 /* if battery can't report average value, use momentary */ 138 /* if battery can't report average value, use momentary */
115 if (MPSY_PROP(CURRENT_NOW, &I)) 139 if (_MPSY_PROP(cur_now_prop, &cur))
116 return -1; 140 return -1;
117 } 141 }
118 142
119 if (status == POWER_SUPPLY_STATUS_CHARGING) 143 if (status == POWER_SUPPLY_STATUS_CHARGING)
120 return ((charge.intval - charge_full.intval) * 60L) / 144 return ((cur.intval - full.intval) * 60L) / I.intval;
121 I.intval;
122 else 145 else
123 return -((charge.intval - charge_empty.intval) * 60L) / 146 return -((cur.intval - empty.intval) * 60L) / I.intval;
124 I.intval;
125} 147}
126 148
127static int calculate_capacity(int using_charge) 149static int calculate_capacity(int using_charge)
@@ -238,16 +260,22 @@ static void apm_battery_apm_get_power_status(struct apm_power_info *info)
238 260
239 if (status.intval == POWER_SUPPLY_STATUS_CHARGING) { 261 if (status.intval == POWER_SUPPLY_STATUS_CHARGING) {
240 if (!MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full) || 262 if (!MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full) ||
241 !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) 263 !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) {
242 info->time = time_to_full.intval / 60; 264 info->time = time_to_full.intval / 60;
243 else 265 } else {
244 info->time = calculate_time(status.intval); 266 info->time = calculate_time(status.intval, 0);
267 if (info->time == -1)
268 info->time = calculate_time(status.intval, 1);
269 }
245 } else { 270 } else {
246 if (!MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty) || 271 if (!MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty) ||
247 !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) 272 !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) {
248 info->time = time_to_empty.intval / 60; 273 info->time = time_to_empty.intval / 60;
249 else 274 } else {
250 info->time = calculate_time(status.intval); 275 info->time = calculate_time(status.intval, 0);
276 if (info->time == -1)
277 info->time = calculate_time(status.intval, 1);
278 }
251 } 279 }
252 280
253 up(&power_supply_class->sem); 281 up(&power_supply_class->sem);