1Charger Manager 2 (C) 2011 MyungJoo Ham <myungjoo.ham@samsung.com>, GPL 3 4Charger Manager provides in-kernel battery charger management that 5requires temperature monitoring during suspend-to-RAM state 6and where each battery may have multiple chargers attached and the userland 7wants to look at the aggregated information of the multiple chargers. 8 9Charger Manager is a platform_driver with power-supply-class entries. 10An instance of Charger Manager (a platform-device created with Charger-Manager) 11represents an independent battery with chargers. If there are multiple 12batteries with their own chargers acting independently in a system, 13the system may need multiple instances of Charger Manager. 14 151. Introduction 16=============== 17 18Charger Manager supports the following: 19 20* Support for multiple chargers (e.g., a device with USB, AC, and solar panels) 21 A system may have multiple chargers (or power sources) and some of 22 they may be activated at the same time. Each charger may have its 23 own power-supply-class and each power-supply-class can provide 24 different information about the battery status. This framework 25 aggregates charger-related information from multiple sources and 26 shows combined information as a single power-supply-class. 27 28* Support for in suspend-to-RAM polling (with suspend_again callback) 29 While the battery is being charged and the system is in suspend-to-RAM, 30 we may need to monitor the battery health by looking at the ambient or 31 battery temperature. We can accomplish this by waking up the system 32 periodically. However, such a method wakes up devices unnecessarily for 33 monitoring the battery health and tasks, and user processes that are 34 supposed to be kept suspended. That, in turn, incurs unnecessary power 35 consumption and slow down charging process. Or even, such peak power 36 consumption can stop chargers in the middle of charging 37 (external power input < device power consumption), which not 38 only affects the charging time, but the lifespan of the battery. 39 40 Charger Manager provides a function "cm_suspend_again" that can be 41 used as suspend_again callback of platform_suspend_ops. If the platform 42 requires tasks other than cm_suspend_again, it may implement its own 43 suspend_again callback that calls cm_suspend_again in the middle. 44 Normally, the platform will need to resume and suspend some devices 45 that are used by Charger Manager. 46 47* Support for premature full-battery event handling 48 If the battery voltage drops by "fullbatt_vchkdrop_uV" after 49 "fullbatt_vchkdrop_ms" from the full-battery event, the framework 50 restarts charging. This check is also performed while suspended by 51 setting wakeup time accordingly and using suspend_again. 52 53* Support for uevent-notify 54 With the charger-related events, the device sends 55 notification to users with UEVENT. 56 572. Global Charger-Manager Data related with suspend_again 58======================================================== 59In order to setup Charger Manager with suspend-again feature 60(in-suspend monitoring), the user should provide charger_global_desc 61with setup_charger_manager(struct charger_global_desc *). 62This charger_global_desc data for in-suspend monitoring is global 63as the name suggests. Thus, the user needs to provide only once even 64if there are multiple batteries. If there are multiple batteries, the 65multiple instances of Charger Manager share the same charger_global_desc 66and it will manage in-suspend monitoring for all instances of Charger Manager. 67 68The user needs to provide all the three entries properly in order to activate 69in-suspend monitoring: 70 71struct charger_global_desc { 72 73char *rtc_name; 74 : The name of rtc (e.g., "rtc0") used to wakeup the system from 75 suspend for Charger Manager. The alarm interrupt (AIE) of the rtc 76 should be able to wake up the system from suspend. Charger Manager 77 saves and restores the alarm value and use the previously-defined 78 alarm if it is going to go off earlier than Charger Manager so that 79 Charger Manager does not interfere with previously-defined alarms. 80 81bool (*rtc_only_wakeup)(void); 82 : This callback should let CM know whether 83 the wakeup-from-suspend is caused only by the alarm of "rtc" in the 84 same struct. If there is any other wakeup source triggered the 85 wakeup, it should return false. If the "rtc" is the only wakeup 86 reason, it should return true. 87 88bool assume_timer_stops_in_suspend; 89 : if true, Charger Manager assumes that 90 the timer (CM uses jiffies as timer) stops during suspend. Then, CM 91 assumes that the suspend-duration is same as the alarm length. 92}; 93 943. How to setup suspend_again 95============================= 96Charger Manager provides a function "extern bool cm_suspend_again(void)". 97When cm_suspend_again is called, it monitors every battery. The suspend_ops 98callback of the system's platform_suspend_ops can call cm_suspend_again 99function to know whether Charger Manager wants to suspend again or not. 100If there are no other devices or tasks that want to use suspend_again 101feature, the platform_suspend_ops may directly refer to cm_suspend_again 102for its suspend_again callback. 103 104The cm_suspend_again() returns true (meaning "I want to suspend again") 105if the system was woken up by Charger Manager and the polling 106(in-suspend monitoring) results in "normal". 107 1084. Charger-Manager Data (struct charger_desc) 109============================================= 110For each battery charged independently from other batteries (if a series of 111batteries are charged by a single charger, they are counted as one independent 112battery), an instance of Charger Manager is attached to it. 113 114struct charger_desc { 115 116char *psy_name; 117 : The power-supply-class name of the battery. Default is 118 "battery" if psy_name is NULL. Users can access the psy entries 119 at "/sys/class/power_supply/[psy_name]/". 120 121enum polling_modes polling_mode; 122 : CM_POLL_DISABLE: do not poll this battery. 123 CM_POLL_ALWAYS: always poll this battery. 124 CM_POLL_EXTERNAL_POWER_ONLY: poll this battery if and only if 125 an external power source is attached. 126 CM_POLL_CHARGING_ONLY: poll this battery if and only if the 127 battery is being charged. 128 129unsigned int fullbatt_vchkdrop_ms; 130unsigned int fullbatt_vchkdrop_uV; 131 : If both have non-zero values, Charger Manager will check the 132 battery voltage drop fullbatt_vchkdrop_ms after the battery is fully 133 charged. If the voltage drop is over fullbatt_vchkdrop_uV, Charger 134 Manager will try to recharge the battery by disabling and enabling 135 chargers. Recharge with voltage drop condition only (without delay 136 condition) is needed to be implemented with hardware interrupts from 137 fuel gauges or charger devices/chips. 138 139unsigned int fullbatt_uV; 140 : If specified with a non-zero value, Charger Manager assumes 141 that the battery is full (capacity = 100) if the battery is not being 142 charged and the battery voltage is equal to or greater than 143 fullbatt_uV. 144 145unsigned int polling_interval_ms; 146 : Required polling interval in ms. Charger Manager will poll 147 this battery every polling_interval_ms or more frequently. 148 149enum data_source battery_present; 150 : CM_BATTERY_PRESENT: assume that the battery exists. 151 CM_NO_BATTERY: assume that the battery does not exists. 152 CM_FUEL_GAUGE: get battery presence information from fuel gauge. 153 CM_CHARGER_STAT: get battery presence from chargers. 154 155char **psy_charger_stat; 156 : An array ending with NULL that has power-supply-class names of 157 chargers. Each power-supply-class should provide "PRESENT" (if 158 battery_present is "CM_CHARGER_STAT"), "ONLINE" (shows whether an 159 external power source is attached or not), and "STATUS" (shows whether 160 the battery is {"FULL" or not FULL} or {"FULL", "Charging", 161 "Discharging", "NotCharging"}). 162 163int num_charger_regulators; 164struct regulator_bulk_data *charger_regulators; 165 : Regulators representing the chargers in the form for 166 regulator framework's bulk functions. 167 168char *psy_fuel_gauge; 169 : Power-supply-class name of the fuel gauge. 170 171int (*temperature_out_of_range)(int *mC); 172bool measure_battery_temp; 173 : This callback returns 0 if the temperature is safe for charging, 174 a positive number if it is too hot to charge, and a negative number 175 if it is too cold to charge. With the variable mC, the callback returns 176 the temperature in 1/1000 of centigrade. 177 The source of temperature can be battery or ambient one according to 178 the value of measure_battery_temp. 179}; 180 1815. Notify Charger-Manager of charger events: cm_notify_event() 182========================================================= 183If there is an charger event is required to notify 184Charger Manager, a charger device driver that triggers the event can call 185cm_notify_event(psy, type, msg) to notify the corresponding Charger Manager. 186In the function, psy is the charger driver's power_supply pointer, which is 187associated with Charger-Manager. The parameter "type" 188is the same as irq's type (enum cm_event_types). The event message "msg" is 189optional and is effective only if the event type is "UNDESCRIBED" or "OTHERS". 190 1916. Other Considerations 192======================= 193 194At the charger/battery-related events such as battery-pulled-out, 195charger-pulled-out, charger-inserted, DCIN-over/under-voltage, charger-stopped, 196and others critical to chargers, the system should be configured to wake up. 197At least the following should wake up the system from a suspend: 198a) charger-on/off b) external-power-in/out c) battery-in/out (while charging) 199 200It is usually accomplished by configuring the PMIC as a wakeup source. 201