1 /* 2 * Copyright (C) 2011 Samsung Electronics Co., Ltd. 3 * MyungJoo.Ham <myungjoo.ham@samsung.com> 4 * 5 * Charger Manager. 6 * This framework enables to control and multiple chargers and to 7 * monitor charging even in the context of suspend-to-RAM with 8 * an interface combining the chargers. 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 **/ 14 15 #ifndef _CHARGER_MANAGER_H 16 #define _CHARGER_MANAGER_H 17 18 #include <linux/power_supply.h> 19 #include <linux/extcon.h> 20 21 enum data_source { 22 CM_BATTERY_PRESENT, 23 CM_NO_BATTERY, 24 CM_FUEL_GAUGE, 25 CM_CHARGER_STAT, 26 }; 27 28 enum polling_modes { 29 CM_POLL_DISABLE = 0, 30 CM_POLL_ALWAYS, 31 CM_POLL_EXTERNAL_POWER_ONLY, 32 CM_POLL_CHARGING_ONLY, 33 }; 34 35 enum cm_event_types { 36 CM_EVENT_UNKNOWN = 0, 37 CM_EVENT_BATT_FULL, 38 CM_EVENT_BATT_IN, 39 CM_EVENT_BATT_OUT, 40 CM_EVENT_EXT_PWR_IN_OUT, 41 CM_EVENT_CHG_START_STOP, 42 CM_EVENT_OTHERS, 43 }; 44 45 /** 46 * struct charger_global_desc 47 * @rtc_name: the name of RTC used to wake up the system from suspend. 48 * @rtc_only_wakeup: 49 * If the system is woken up by waekup-sources other than the RTC or 50 * callbacks, Charger Manager should recognize with 51 * rtc_only_wakeup() returning false. 52 * If the RTC given to CM is the only wakeup reason, 53 * rtc_only_wakeup should return true. 54 * @assume_timer_stops_in_suspend: 55 * Assume that the jiffy timer stops in suspend-to-RAM. 56 * When enabled, CM does not rely on jiffies value in 57 * suspend_again and assumes that jiffies value does not 58 * change during suspend. 59 */ 60 struct charger_global_desc { 61 char *rtc_name; 62 63 bool (*rtc_only_wakeup)(void); 64 65 bool assume_timer_stops_in_suspend; 66 }; 67 68 /** 69 * struct charger_cable 70 * @extcon_name: the name of extcon device. 71 * @name: the name of charger cable(external connector). 72 * @extcon_dev: the extcon device. 73 * @wq: the workqueue to control charger according to the state of 74 * charger cable. If charger cable is attached, enable charger. 75 * But if charger cable is detached, disable charger. 76 * @nb: the notifier block to receive changed state from EXTCON 77 * (External Connector) when charger cable is attached/detached. 78 * @attached: the state of charger cable. 79 * true: the charger cable is attached 80 * false: the charger cable is detached 81 * @charger: the instance of struct charger_regulator. 82 * @cm: the Charger Manager representing the battery. 83 */ 84 struct charger_cable { 85 const char *extcon_name; 86 const char *name; 87 88 /* The charger-manager use Exton framework*/ 89 struct extcon_specific_cable_nb extcon_dev; 90 struct work_struct wq; 91 struct notifier_block nb; 92 93 /* The state of charger cable */ 94 bool attached; 95 96 struct charger_regulator *charger; 97 98 /* 99 * Set min/max current of regulator to protect over-current issue 100 * according to a kind of charger cable when cable is attached. 101 */ 102 int min_uA; 103 int max_uA; 104 105 struct charger_manager *cm; 106 }; 107 108 /** 109 * struct charger_regulator 110 * @regulator_name: the name of regulator for using charger. 111 * @consumer: the regulator consumer for the charger. 112 * @externally_control: 113 * Set if the charger-manager cannot control charger, 114 * the charger will be maintained with disabled state. 115 * @cables: 116 * the array of charger cables to enable/disable charger 117 * and set current limit according to constratint data of 118 * struct charger_cable if only charger cable included 119 * in the array of charger cables is attached/detached. 120 * @num_cables: the number of charger cables. 121 * @attr_g: Attribute group for the charger(regulator) 122 * @attr_name: "name" sysfs entry 123 * @attr_state: "state" sysfs entry 124 * @attr_externally_control: "externally_control" sysfs entry 125 * @attrs: Arrays pointing to attr_name/state/externally_control for attr_g 126 */ 127 struct charger_regulator { 128 /* The name of regulator for charging */ 129 const char *regulator_name; 130 struct regulator *consumer; 131 132 /* charger never on when system is on */ 133 int externally_control; 134 135 /* 136 * Store constraint information related to current limit, 137 * each cable have different condition for charging. 138 */ 139 struct charger_cable *cables; 140 int num_cables; 141 142 struct attribute_group attr_g; 143 struct device_attribute attr_name; 144 struct device_attribute attr_state; 145 struct device_attribute attr_externally_control; 146 struct attribute *attrs[4]; 147 148 struct charger_manager *cm; 149 }; 150 151 /** 152 * struct charger_desc 153 * @psy_name: the name of power-supply-class for charger manager 154 * @polling_mode: 155 * Determine which polling mode will be used 156 * @fullbatt_vchkdrop_ms: 157 * @fullbatt_vchkdrop_uV: 158 * Check voltage drop after the battery is fully charged. 159 * If it has dropped more than fullbatt_vchkdrop_uV after 160 * fullbatt_vchkdrop_ms, CM will restart charging. 161 * @fullbatt_uV: voltage in microvolt 162 * If VBATT >= fullbatt_uV, it is assumed to be full. 163 * @fullbatt_soc: state of Charge in % 164 * If state of Charge >= fullbatt_soc, it is assumed to be full. 165 * @fullbatt_full_capacity: full capacity measure 166 * If full capacity of battery >= fullbatt_full_capacity, 167 * it is assumed to be full. 168 * @polling_interval_ms: interval in millisecond at which 169 * charger manager will monitor battery health 170 * @battery_present: 171 * Specify where information for existance of battery can be obtained 172 * @psy_charger_stat: the names of power-supply for chargers 173 * @num_charger_regulator: the number of entries in charger_regulators 174 * @charger_regulators: array of charger regulators 175 * @psy_fuel_gauge: the name of power-supply for fuel gauge 176 * @temperature_out_of_range: 177 * Determine whether the status is overheat or cold or normal. 178 * return_value > 0: overheat 179 * return_value == 0: normal 180 * return_value < 0: cold 181 * @measure_battery_temp: 182 * true: measure battery temperature 183 * false: measure ambient temperature 184 * @charging_max_duration_ms: Maximum possible duration for charging 185 * If whole charging duration exceed 'charging_max_duration_ms', 186 * cm stop charging. 187 * @discharging_max_duration_ms: 188 * Maximum possible duration for discharging with charger cable 189 * after full-batt. If discharging duration exceed 'discharging 190 * max_duration_ms', cm start charging. 191 */ 192 struct charger_desc { 193 char *psy_name; 194 195 enum polling_modes polling_mode; 196 unsigned int polling_interval_ms; 197 198 unsigned int fullbatt_vchkdrop_ms; 199 unsigned int fullbatt_vchkdrop_uV; 200 unsigned int fullbatt_uV; 201 unsigned int fullbatt_soc; 202 unsigned int fullbatt_full_capacity; 203 204 enum data_source battery_present; 205 206 char **psy_charger_stat; 207 208 int num_charger_regulators; 209 struct charger_regulator *charger_regulators; 210 211 char *psy_fuel_gauge; 212 213 int (*temperature_out_of_range)(int *mC); 214 bool measure_battery_temp; 215 216 u64 charging_max_duration_ms; 217 u64 discharging_max_duration_ms; 218 }; 219 220 #define PSY_NAME_MAX 30 221 222 /** 223 * struct charger_manager 224 * @entry: entry for list 225 * @dev: device pointer 226 * @desc: instance of charger_desc 227 * @fuel_gauge: power_supply for fuel gauge 228 * @charger_stat: array of power_supply for chargers 229 * @charger_enabled: the state of charger 230 * @fullbatt_vchk_jiffies_at: 231 * jiffies at the time full battery check will occur. 232 * @fullbatt_vchk_work: work queue for full battery check 233 * @emergency_stop: 234 * When setting true, stop charging 235 * @last_temp_mC: the measured temperature in milli-Celsius 236 * @psy_name_buf: the name of power-supply-class for charger manager 237 * @charger_psy: power_supply for charger manager 238 * @status_save_ext_pwr_inserted: 239 * saved status of external power before entering suspend-to-RAM 240 * @status_save_batt: 241 * saved status of battery before entering suspend-to-RAM 242 * @charging_start_time: saved start time of enabling charging 243 * @charging_end_time: saved end time of disabling charging 244 */ 245 struct charger_manager { 246 struct list_head entry; 247 struct device *dev; 248 struct charger_desc *desc; 249 250 struct power_supply *fuel_gauge; 251 struct power_supply **charger_stat; 252 253 bool charger_enabled; 254 255 unsigned long fullbatt_vchk_jiffies_at; 256 struct delayed_work fullbatt_vchk_work; 257 258 int emergency_stop; 259 int last_temp_mC; 260 261 char psy_name_buf[PSY_NAME_MAX + 1]; 262 struct power_supply charger_psy; 263 264 bool status_save_ext_pwr_inserted; 265 bool status_save_batt; 266 267 u64 charging_start_time; 268 u64 charging_end_time; 269 }; 270 271 #ifdef CONFIG_CHARGER_MANAGER 272 extern int setup_charger_manager(struct charger_global_desc *gd); 273 extern bool cm_suspend_again(void); 274 extern void cm_notify_event(struct power_supply *psy, 275 enum cm_event_types type, char *msg); 276 #else 277 static inline int setup_charger_manager(struct charger_global_desc *gd) 278 { return 0; } 279 static inline bool cm_suspend_again(void) { return false; } 280 static inline void cm_notify_event(struct power_supply *psy, 281 enum cm_event_types type, char *msg) { } 282 #endif 283 #endif /* _CHARGER_MANAGER_H */ 284