diff options
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/apm_power.c | 78 |
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 | ||
90 | static int calculate_time(int status) | 90 | static 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 | ||
127 | static int calculate_capacity(int using_charge) | 149 | static 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); |