Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
apm_emu.c
Go to the documentation of this file.
1 /*
2  * APM emulation for PMU-based machines
3  *
4  * Copyright 2001 Benjamin Herrenschmidt ([email protected])
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2, or (at your option) any
9  * later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  *
17  */
18 
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/apm-emulation.h>
22 #include <linux/adb.h>
23 #include <linux/pmu.h>
24 
25 #define APM_CRITICAL 10
26 #define APM_LOW 30
27 
28 static void pmu_apm_get_power_status(struct apm_power_info *info)
29 {
30  int percentage = -1;
31  int batteries = 0;
32  int time_units = -1;
33  int real_count = 0;
34  int i;
35  char charging = 0;
36  long charge = -1;
37  long amperage = 0;
38  unsigned long btype = 0;
39 
42  info->units = APM_UNITS_MINS;
43 
46  else
48 
49  for (i=0; i<pmu_battery_count; i++) {
51  batteries++;
52  if (percentage < 0)
53  percentage = 0;
54  if (charge < 0)
55  charge = 0;
56  percentage += (pmu_batteries[i].charge * 100) /
57  pmu_batteries[i].max_charge;
58  charge += pmu_batteries[i].charge;
59  amperage += pmu_batteries[i].amperage;
60  if (btype == 0)
61  btype = (pmu_batteries[i].flags & PMU_BATT_TYPE_MASK);
62  real_count++;
64  charging++;
65  }
66  }
67  if (batteries == 0)
69 
70  if (real_count) {
71  if (amperage < 0) {
72  if (btype == PMU_BATT_TYPE_SMART)
73  time_units = (charge * 59) / (amperage * -1);
74  else
75  time_units = (charge * 16440) / (amperage * -60);
76  }
77  percentage /= real_count;
78  if (charging > 0) {
81  } else if (percentage <= APM_CRITICAL) {
84  } else if (percentage <= APM_LOW) {
87  } else {
90  }
91  }
92 
93  info->battery_life = percentage;
94  info->time = time_units;
95 }
96 
97 static int __init apm_emu_init(void)
98 {
99  apm_get_power_status = pmu_apm_get_power_status;
100 
101  printk(KERN_INFO "apm_emu: PMU APM Emulation initialized.\n");
102 
103  return 0;
104 }
105 
106 static void __exit apm_emu_exit(void)
107 {
108  if (apm_get_power_status == pmu_apm_get_power_status)
110 
111  printk(KERN_INFO "apm_emu: PMU APM Emulation removed.\n");
112 }
113 
114 module_init(apm_emu_init);
115 module_exit(apm_emu_exit);
116 
117 MODULE_AUTHOR("Benjamin Herrenschmidt");
118 MODULE_DESCRIPTION("APM emulation for PowerMac");
119 MODULE_LICENSE("GPL");