apm_power: support using VOLTAGE_* properties for apm calculations

It's pretty dummy, but useful for batteries for which we can only
get voltages.

Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
Signed-off-by: Anton Vorontsov <cbou@mail.ru>

authored by Dmitry Baryshkov and committed by Anton Vorontsov dffd28a1 8f8e9b38

+70 -21
+70 -21
drivers/power/apm_power.c
··· 13 13 #include <linux/power_supply.h> 14 14 #include <linux/apm-emulation.h> 15 15 16 - static DEFINE_MUTEX(apm_mutex); 16 + 17 17 #define PSY_PROP(psy, prop, val) psy->get_property(psy, \ 18 18 POWER_SUPPLY_PROP_##prop, val) 19 19 ··· 22 22 23 23 #define MPSY_PROP(prop, val) _MPSY_PROP(POWER_SUPPLY_PROP_##prop, val) 24 24 25 + static DEFINE_MUTEX(apm_mutex); 25 26 static struct power_supply *main_battery; 27 + 28 + enum apm_source { 29 + SOURCE_ENERGY, 30 + SOURCE_CHARGE, 31 + SOURCE_VOLTAGE, 32 + }; 26 33 27 34 struct find_bat_param { 28 35 struct power_supply *main; ··· 114 107 } 115 108 } 116 109 117 - static int calculate_time(int status, int using_charge) 110 + static int do_calculate_time(int status, enum apm_source source) 118 111 { 119 112 union power_supply_propval full; 120 113 union power_supply_propval empty; ··· 133 126 return -1; 134 127 } 135 128 136 - if (using_charge) { 129 + switch (source) { 130 + case SOURCE_CHARGE: 137 131 full_prop = POWER_SUPPLY_PROP_CHARGE_FULL; 138 132 full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; 139 133 empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; 140 134 empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; 141 135 cur_avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG; 142 136 cur_now_prop = POWER_SUPPLY_PROP_CHARGE_NOW; 143 - } else { 137 + break; 138 + case SOURCE_ENERGY: 144 139 full_prop = POWER_SUPPLY_PROP_ENERGY_FULL; 145 140 full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; 146 141 empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY; 147 142 empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; 148 143 cur_avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; 149 144 cur_now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; 145 + break; 146 + case SOURCE_VOLTAGE: 147 + full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; 148 + full_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN; 149 + empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; 150 + empty_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN; 151 + cur_avg_prop = POWER_SUPPLY_PROP_VOLTAGE_AVG; 152 + cur_now_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW; 153 + break; 154 + default: 155 + printk(KERN_ERR "Unsupported source: %d\n", source); 156 + return -1; 150 157 } 151 158 152 159 if (_MPSY_PROP(full_prop, &full)) { ··· 187 166 return -((cur.intval - empty.intval) * 60L) / I.intval; 188 167 } 189 168 190 - static int calculate_capacity(int using_charge) 169 + static int calculate_time(int status) 170 + { 171 + int time; 172 + 173 + time = do_calculate_time(status, SOURCE_ENERGY); 174 + if (time != -1) 175 + return time; 176 + 177 + time = do_calculate_time(status, SOURCE_CHARGE); 178 + if (time != -1) 179 + return time; 180 + 181 + time = do_calculate_time(status, SOURCE_VOLTAGE); 182 + if (time != -1) 183 + return time; 184 + 185 + return -1; 186 + } 187 + 188 + static int calculate_capacity(enum apm_source source) 191 189 { 192 190 enum power_supply_property full_prop, empty_prop; 193 191 enum power_supply_property full_design_prop, empty_design_prop; ··· 214 174 union power_supply_propval empty, full, cur; 215 175 int ret; 216 176 217 - if (using_charge) { 177 + switch (source) { 178 + case SOURCE_CHARGE: 218 179 full_prop = POWER_SUPPLY_PROP_CHARGE_FULL; 219 180 empty_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY; 220 181 full_design_prop = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; 221 182 empty_design_prop = POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN; 222 183 now_prop = POWER_SUPPLY_PROP_CHARGE_NOW; 223 184 avg_prop = POWER_SUPPLY_PROP_CHARGE_AVG; 224 - } else { 185 + break; 186 + case SOURCE_ENERGY: 225 187 full_prop = POWER_SUPPLY_PROP_ENERGY_FULL; 226 188 empty_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY; 227 189 full_design_prop = POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN; 228 190 empty_design_prop = POWER_SUPPLY_PROP_ENERGY_EMPTY_DESIGN; 229 191 now_prop = POWER_SUPPLY_PROP_ENERGY_NOW; 230 192 avg_prop = POWER_SUPPLY_PROP_ENERGY_AVG; 193 + case SOURCE_VOLTAGE: 194 + full_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX; 195 + empty_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN; 196 + full_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN; 197 + empty_design_prop = POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN; 198 + now_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW; 199 + avg_prop = POWER_SUPPLY_PROP_VOLTAGE_AVG; 200 + break; 201 + default: 202 + printk(KERN_ERR "Unsupported source: %d\n", source); 203 + return -1; 231 204 } 232 205 233 206 if (_MPSY_PROP(full_prop, &full)) { ··· 307 254 info->battery_life = capacity.intval; 308 255 } else { 309 256 /* try calculate using energy */ 310 - info->battery_life = calculate_capacity(0); 257 + info->battery_life = calculate_capacity(SOURCE_ENERGY); 311 258 /* if failed try calculate using charge instead */ 312 259 if (info->battery_life == -1) 313 - info->battery_life = calculate_capacity(1); 260 + info->battery_life = calculate_capacity(SOURCE_CHARGE); 261 + if (info->battery_life == -1) 262 + info->battery_life = calculate_capacity(SOURCE_VOLTAGE); 314 263 } 315 264 316 265 /* charging status */ ··· 335 280 336 281 if (status.intval == POWER_SUPPLY_STATUS_CHARGING) { 337 282 if (!MPSY_PROP(TIME_TO_FULL_AVG, &time_to_full) || 338 - !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) { 283 + !MPSY_PROP(TIME_TO_FULL_NOW, &time_to_full)) 339 284 info->time = time_to_full.intval / 60; 340 - } else { 341 - info->time = calculate_time(status.intval, 0); 342 - if (info->time == -1) 343 - info->time = calculate_time(status.intval, 1); 344 - } 285 + else 286 + info->time = calculate_time(status.intval); 345 287 } else { 346 288 if (!MPSY_PROP(TIME_TO_EMPTY_AVG, &time_to_empty) || 347 - !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) { 289 + !MPSY_PROP(TIME_TO_EMPTY_NOW, &time_to_empty)) 348 290 info->time = time_to_empty.intval / 60; 349 - } else { 350 - info->time = calculate_time(status.intval, 0); 351 - if (info->time == -1) 352 - info->time = calculate_time(status.intval, 1); 353 - } 291 + else 292 + info->time = calculate_time(status.intval); 354 293 } 355 294 356 295 mutex_unlock(&apm_mutex);