charger-manager.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908
  1. /*
  2. * Copyright (C) 2011 Samsung Electronics Co., Ltd.
  3. * MyungJoo Ham <myungjoo.ham@samsung.com>
  4. *
  5. * This driver enables to monitor battery health and control charger
  6. * during suspend-to-mem.
  7. * Charger manager depends on other devices. register this later than
  8. * the depending devices.
  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. #include <linux/io.h>
  15. #include <linux/module.h>
  16. #include <linux/irq.h>
  17. #include <linux/interrupt.h>
  18. #include <linux/rtc.h>
  19. #include <linux/slab.h>
  20. #include <linux/workqueue.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/power/charger-manager.h>
  23. #include <linux/regulator/consumer.h>
  24. #include <linux/sysfs.h>
  25. static const char * const default_event_names[] = {
  26. [CM_EVENT_UNKNOWN] = "Unknown",
  27. [CM_EVENT_BATT_FULL] = "Battery Full",
  28. [CM_EVENT_BATT_IN] = "Battery Inserted",
  29. [CM_EVENT_BATT_OUT] = "Battery Pulled Out",
  30. [CM_EVENT_EXT_PWR_IN_OUT] = "External Power Attach/Detach",
  31. [CM_EVENT_CHG_START_STOP] = "Charging Start/Stop",
  32. [CM_EVENT_OTHERS] = "Other battery events"
  33. };
  34. /*
  35. * Regard CM_JIFFIES_SMALL jiffies is small enough to ignore for
  36. * delayed works so that we can run delayed works with CM_JIFFIES_SMALL
  37. * without any delays.
  38. */
  39. #define CM_JIFFIES_SMALL (2)
  40. /* If y is valid (> 0) and smaller than x, do x = y */
  41. #define CM_MIN_VALID(x, y) x = (((y > 0) && ((x) > (y))) ? (y) : (x))
  42. /*
  43. * Regard CM_RTC_SMALL (sec) is small enough to ignore error in invoking
  44. * rtc alarm. It should be 2 or larger
  45. */
  46. #define CM_RTC_SMALL (2)
  47. #define UEVENT_BUF_SIZE 32
  48. static LIST_HEAD(cm_list);
  49. static DEFINE_MUTEX(cm_list_mtx);
  50. /* About in-suspend (suspend-again) monitoring */
  51. static struct rtc_device *rtc_dev;
  52. /*
  53. * Backup RTC alarm
  54. * Save the wakeup alarm before entering suspend-to-RAM
  55. */
  56. static struct rtc_wkalrm rtc_wkalarm_save;
  57. /* Backup RTC alarm time in terms of seconds since 01-01-1970 00:00:00 */
  58. static unsigned long rtc_wkalarm_save_time;
  59. static bool cm_suspended;
  60. static bool cm_rtc_set;
  61. static unsigned long cm_suspend_duration_ms;
  62. /* About normal (not suspended) monitoring */
  63. static unsigned long polling_jiffy = ULONG_MAX; /* ULONG_MAX: no polling */
  64. static unsigned long next_polling; /* Next appointed polling time */
  65. static struct workqueue_struct *cm_wq; /* init at driver add */
  66. static struct delayed_work cm_monitor_work; /* init at driver add */
  67. /* Global charger-manager description */
  68. static struct charger_global_desc *g_desc; /* init with setup_charger_manager */
  69. /**
  70. * is_batt_present - See if the battery presents in place.
  71. * @cm: the Charger Manager representing the battery.
  72. */
  73. static bool is_batt_present(struct charger_manager *cm)
  74. {
  75. union power_supply_propval val;
  76. bool present = false;
  77. int i, ret;
  78. switch (cm->desc->battery_present) {
  79. case CM_BATTERY_PRESENT:
  80. present = true;
  81. break;
  82. case CM_NO_BATTERY:
  83. break;
  84. case CM_FUEL_GAUGE:
  85. ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
  86. POWER_SUPPLY_PROP_PRESENT, &val);
  87. if (ret == 0 && val.intval)
  88. present = true;
  89. break;
  90. case CM_CHARGER_STAT:
  91. for (i = 0; cm->charger_stat[i]; i++) {
  92. ret = cm->charger_stat[i]->get_property(
  93. cm->charger_stat[i],
  94. POWER_SUPPLY_PROP_PRESENT, &val);
  95. if (ret == 0 && val.intval) {
  96. present = true;
  97. break;
  98. }
  99. }
  100. break;
  101. }
  102. return present;
  103. }
  104. /**
  105. * is_ext_pwr_online - See if an external power source is attached to charge
  106. * @cm: the Charger Manager representing the battery.
  107. *
  108. * Returns true if at least one of the chargers of the battery has an external
  109. * power source attached to charge the battery regardless of whether it is
  110. * actually charging or not.
  111. */
  112. static bool is_ext_pwr_online(struct charger_manager *cm)
  113. {
  114. union power_supply_propval val;
  115. bool online = false;
  116. int i, ret;
  117. /* If at least one of them has one, it's yes. */
  118. for (i = 0; cm->charger_stat[i]; i++) {
  119. ret = cm->charger_stat[i]->get_property(
  120. cm->charger_stat[i],
  121. POWER_SUPPLY_PROP_ONLINE, &val);
  122. if (ret == 0 && val.intval) {
  123. online = true;
  124. break;
  125. }
  126. }
  127. return online;
  128. }
  129. /**
  130. * get_batt_uV - Get the voltage level of the battery
  131. * @cm: the Charger Manager representing the battery.
  132. * @uV: the voltage level returned.
  133. *
  134. * Returns 0 if there is no error.
  135. * Returns a negative value on error.
  136. */
  137. static int get_batt_uV(struct charger_manager *cm, int *uV)
  138. {
  139. union power_supply_propval val;
  140. int ret;
  141. if (!cm->fuel_gauge)
  142. return -ENODEV;
  143. ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
  144. POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
  145. if (ret)
  146. return ret;
  147. *uV = val.intval;
  148. return 0;
  149. }
  150. /**
  151. * is_charging - Returns true if the battery is being charged.
  152. * @cm: the Charger Manager representing the battery.
  153. */
  154. static bool is_charging(struct charger_manager *cm)
  155. {
  156. int i, ret;
  157. bool charging = false;
  158. union power_supply_propval val;
  159. /* If there is no battery, it cannot be charged */
  160. if (!is_batt_present(cm))
  161. return false;
  162. /* If at least one of the charger is charging, return yes */
  163. for (i = 0; cm->charger_stat[i]; i++) {
  164. /* 1. The charger sholuld not be DISABLED */
  165. if (cm->emergency_stop)
  166. continue;
  167. if (!cm->charger_enabled)
  168. continue;
  169. /* 2. The charger should be online (ext-power) */
  170. ret = cm->charger_stat[i]->get_property(
  171. cm->charger_stat[i],
  172. POWER_SUPPLY_PROP_ONLINE, &val);
  173. if (ret) {
  174. dev_warn(cm->dev, "Cannot read ONLINE value from %s.\n",
  175. cm->desc->psy_charger_stat[i]);
  176. continue;
  177. }
  178. if (val.intval == 0)
  179. continue;
  180. /*
  181. * 3. The charger should not be FULL, DISCHARGING,
  182. * or NOT_CHARGING.
  183. */
  184. ret = cm->charger_stat[i]->get_property(
  185. cm->charger_stat[i],
  186. POWER_SUPPLY_PROP_STATUS, &val);
  187. if (ret) {
  188. dev_warn(cm->dev, "Cannot read STATUS value from %s.\n",
  189. cm->desc->psy_charger_stat[i]);
  190. continue;
  191. }
  192. if (val.intval == POWER_SUPPLY_STATUS_FULL ||
  193. val.intval == POWER_SUPPLY_STATUS_DISCHARGING ||
  194. val.intval == POWER_SUPPLY_STATUS_NOT_CHARGING)
  195. continue;
  196. /* Then, this is charging. */
  197. charging = true;
  198. break;
  199. }
  200. return charging;
  201. }
  202. /**
  203. * is_full_charged - Returns true if the battery is fully charged.
  204. * @cm: the Charger Manager representing the battery.
  205. */
  206. static bool is_full_charged(struct charger_manager *cm)
  207. {
  208. struct charger_desc *desc = cm->desc;
  209. union power_supply_propval val;
  210. int ret = 0;
  211. int uV;
  212. /* If there is no battery, it cannot be charged */
  213. if (!is_batt_present(cm)) {
  214. val.intval = 0;
  215. goto out;
  216. }
  217. if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) {
  218. /* Not full if capacity of fuel gauge isn't full */
  219. ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
  220. POWER_SUPPLY_PROP_CHARGE_FULL, &val);
  221. if (!ret && val.intval > desc->fullbatt_full_capacity) {
  222. val.intval = 1;
  223. goto out;
  224. }
  225. }
  226. /* Full, if it's over the fullbatt voltage */
  227. if (desc->fullbatt_uV > 0) {
  228. ret = get_batt_uV(cm, &uV);
  229. if (!ret && uV >= desc->fullbatt_uV) {
  230. val.intval = 1;
  231. goto out;
  232. }
  233. }
  234. /* Full, if the capacity is more than fullbatt_soc */
  235. if (cm->fuel_gauge && desc->fullbatt_soc > 0) {
  236. ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
  237. POWER_SUPPLY_PROP_CAPACITY, &val);
  238. if (!ret && val.intval >= desc->fullbatt_soc) {
  239. val.intval = 1;
  240. goto out;
  241. }
  242. }
  243. val.intval = 0;
  244. out:
  245. return val.intval ? true : false;
  246. }
  247. /**
  248. * is_polling_required - Return true if need to continue polling for this CM.
  249. * @cm: the Charger Manager representing the battery.
  250. */
  251. static bool is_polling_required(struct charger_manager *cm)
  252. {
  253. switch (cm->desc->polling_mode) {
  254. case CM_POLL_DISABLE:
  255. return false;
  256. case CM_POLL_ALWAYS:
  257. return true;
  258. case CM_POLL_EXTERNAL_POWER_ONLY:
  259. return is_ext_pwr_online(cm);
  260. case CM_POLL_CHARGING_ONLY:
  261. return is_charging(cm);
  262. default:
  263. dev_warn(cm->dev, "Incorrect polling_mode (%d)\n",
  264. cm->desc->polling_mode);
  265. }
  266. return false;
  267. }
  268. /**
  269. * try_charger_enable - Enable/Disable chargers altogether
  270. * @cm: the Charger Manager representing the battery.
  271. * @enable: true: enable / false: disable
  272. *
  273. * Note that Charger Manager keeps the charger enabled regardless whether
  274. * the charger is charging or not (because battery is full or no external
  275. * power source exists) except when CM needs to disable chargers forcibly
  276. * bacause of emergency causes; when the battery is overheated or too cold.
  277. */
  278. static int try_charger_enable(struct charger_manager *cm, bool enable)
  279. {
  280. int err = 0, i;
  281. struct charger_desc *desc = cm->desc;
  282. /* Ignore if it's redundent command */
  283. if (enable == cm->charger_enabled)
  284. return 0;
  285. if (enable) {
  286. if (cm->emergency_stop)
  287. return -EAGAIN;
  288. /*
  289. * Save start time of charging to limit
  290. * maximum possible charging time.
  291. */
  292. cm->charging_start_time = ktime_to_ms(ktime_get());
  293. cm->charging_end_time = 0;
  294. for (i = 0 ; i < desc->num_charger_regulators ; i++) {
  295. if (desc->charger_regulators[i].externally_control)
  296. continue;
  297. err = regulator_enable(desc->charger_regulators[i].consumer);
  298. if (err < 0) {
  299. dev_warn(cm->dev,
  300. "Cannot enable %s regulator\n",
  301. desc->charger_regulators[i].regulator_name);
  302. }
  303. }
  304. } else {
  305. /*
  306. * Save end time of charging to maintain fully charged state
  307. * of battery after full-batt.
  308. */
  309. cm->charging_start_time = 0;
  310. cm->charging_end_time = ktime_to_ms(ktime_get());
  311. for (i = 0 ; i < desc->num_charger_regulators ; i++) {
  312. if (desc->charger_regulators[i].externally_control)
  313. continue;
  314. err = regulator_disable(desc->charger_regulators[i].consumer);
  315. if (err < 0) {
  316. dev_warn(cm->dev,
  317. "Cannot disable %s regulator\n",
  318. desc->charger_regulators[i].regulator_name);
  319. }
  320. }
  321. /*
  322. * Abnormal battery state - Stop charging forcibly,
  323. * even if charger was enabled at the other places
  324. */
  325. for (i = 0; i < desc->num_charger_regulators; i++) {
  326. if (regulator_is_enabled(
  327. desc->charger_regulators[i].consumer)) {
  328. regulator_force_disable(
  329. desc->charger_regulators[i].consumer);
  330. dev_warn(cm->dev,
  331. "Disable regulator(%s) forcibly.\n",
  332. desc->charger_regulators[i].regulator_name);
  333. }
  334. }
  335. }
  336. if (!err)
  337. cm->charger_enabled = enable;
  338. return err;
  339. }
  340. /**
  341. * try_charger_restart - Restart charging.
  342. * @cm: the Charger Manager representing the battery.
  343. *
  344. * Restart charging by turning off and on the charger.
  345. */
  346. static int try_charger_restart(struct charger_manager *cm)
  347. {
  348. int err;
  349. if (cm->emergency_stop)
  350. return -EAGAIN;
  351. err = try_charger_enable(cm, false);
  352. if (err)
  353. return err;
  354. return try_charger_enable(cm, true);
  355. }
  356. /**
  357. * uevent_notify - Let users know something has changed.
  358. * @cm: the Charger Manager representing the battery.
  359. * @event: the event string.
  360. *
  361. * If @event is null, it implies that uevent_notify is called
  362. * by resume function. When called in the resume function, cm_suspended
  363. * should be already reset to false in order to let uevent_notify
  364. * notify the recent event during the suspend to users. While
  365. * suspended, uevent_notify does not notify users, but tracks
  366. * events so that uevent_notify can notify users later after resumed.
  367. */
  368. static void uevent_notify(struct charger_manager *cm, const char *event)
  369. {
  370. static char env_str[UEVENT_BUF_SIZE + 1] = "";
  371. static char env_str_save[UEVENT_BUF_SIZE + 1] = "";
  372. if (cm_suspended) {
  373. /* Nothing in suspended-event buffer */
  374. if (env_str_save[0] == 0) {
  375. if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
  376. return; /* status not changed */
  377. strncpy(env_str_save, event, UEVENT_BUF_SIZE);
  378. return;
  379. }
  380. if (!strncmp(env_str_save, event, UEVENT_BUF_SIZE))
  381. return; /* Duplicated. */
  382. strncpy(env_str_save, event, UEVENT_BUF_SIZE);
  383. return;
  384. }
  385. if (event == NULL) {
  386. /* No messages pending */
  387. if (!env_str_save[0])
  388. return;
  389. strncpy(env_str, env_str_save, UEVENT_BUF_SIZE);
  390. kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
  391. env_str_save[0] = 0;
  392. return;
  393. }
  394. /* status not changed */
  395. if (!strncmp(env_str, event, UEVENT_BUF_SIZE))
  396. return;
  397. /* save the status and notify the update */
  398. strncpy(env_str, event, UEVENT_BUF_SIZE);
  399. kobject_uevent(&cm->dev->kobj, KOBJ_CHANGE);
  400. dev_info(cm->dev, event);
  401. }
  402. /**
  403. * fullbatt_vchk - Check voltage drop some times after "FULL" event.
  404. * @work: the work_struct appointing the function
  405. *
  406. * If a user has designated "fullbatt_vchkdrop_ms/uV" values with
  407. * charger_desc, Charger Manager checks voltage drop after the battery
  408. * "FULL" event. It checks whether the voltage has dropped more than
  409. * fullbatt_vchkdrop_uV by calling this function after fullbatt_vchkrop_ms.
  410. */
  411. static void fullbatt_vchk(struct work_struct *work)
  412. {
  413. struct delayed_work *dwork = to_delayed_work(work);
  414. struct charger_manager *cm = container_of(dwork,
  415. struct charger_manager, fullbatt_vchk_work);
  416. struct charger_desc *desc = cm->desc;
  417. int batt_uV, err, diff;
  418. /* remove the appointment for fullbatt_vchk */
  419. cm->fullbatt_vchk_jiffies_at = 0;
  420. if (!desc->fullbatt_vchkdrop_uV || !desc->fullbatt_vchkdrop_ms)
  421. return;
  422. err = get_batt_uV(cm, &batt_uV);
  423. if (err) {
  424. dev_err(cm->dev, "%s: get_batt_uV error(%d).\n", __func__, err);
  425. return;
  426. }
  427. diff = desc->fullbatt_uV;
  428. diff -= batt_uV;
  429. dev_info(cm->dev, "VBATT dropped %duV after full-batt.\n", diff);
  430. if (diff > desc->fullbatt_vchkdrop_uV) {
  431. try_charger_restart(cm);
  432. uevent_notify(cm, "Recharging");
  433. }
  434. }
  435. /**
  436. * check_charging_duration - Monitor charging/discharging duration
  437. * @cm: the Charger Manager representing the battery.
  438. *
  439. * If whole charging duration exceed 'charging_max_duration_ms',
  440. * cm stop charging to prevent overcharge/overheat. If discharging
  441. * duration exceed 'discharging _max_duration_ms', charger cable is
  442. * attached, after full-batt, cm start charging to maintain fully
  443. * charged state for battery.
  444. */
  445. static int check_charging_duration(struct charger_manager *cm)
  446. {
  447. struct charger_desc *desc = cm->desc;
  448. u64 curr = ktime_to_ms(ktime_get());
  449. u64 duration;
  450. int ret = false;
  451. if (!desc->charging_max_duration_ms &&
  452. !desc->discharging_max_duration_ms)
  453. return ret;
  454. if (cm->charger_enabled) {
  455. duration = curr - cm->charging_start_time;
  456. if (duration > desc->charging_max_duration_ms) {
  457. dev_info(cm->dev, "Charging duration exceed %lldms",
  458. desc->charging_max_duration_ms);
  459. uevent_notify(cm, "Discharging");
  460. try_charger_enable(cm, false);
  461. ret = true;
  462. }
  463. } else if (is_ext_pwr_online(cm) && !cm->charger_enabled) {
  464. duration = curr - cm->charging_end_time;
  465. if (duration > desc->charging_max_duration_ms &&
  466. is_ext_pwr_online(cm)) {
  467. dev_info(cm->dev, "DisCharging duration exceed %lldms",
  468. desc->discharging_max_duration_ms);
  469. uevent_notify(cm, "Recharing");
  470. try_charger_enable(cm, true);
  471. ret = true;
  472. }
  473. }
  474. return ret;
  475. }
  476. /**
  477. * _cm_monitor - Monitor the temperature and return true for exceptions.
  478. * @cm: the Charger Manager representing the battery.
  479. *
  480. * Returns true if there is an event to notify for the battery.
  481. * (True if the status of "emergency_stop" changes)
  482. */
  483. static bool _cm_monitor(struct charger_manager *cm)
  484. {
  485. struct charger_desc *desc = cm->desc;
  486. int temp = desc->temperature_out_of_range(&cm->last_temp_mC);
  487. dev_dbg(cm->dev, "monitoring (%2.2d.%3.3dC)\n",
  488. cm->last_temp_mC / 1000, cm->last_temp_mC % 1000);
  489. /* It has been stopped already */
  490. if (temp && cm->emergency_stop)
  491. return false;
  492. /*
  493. * Check temperature whether overheat or cold.
  494. * If temperature is out of range normal state, stop charging.
  495. */
  496. if (temp) {
  497. cm->emergency_stop = temp;
  498. if (!try_charger_enable(cm, false)) {
  499. if (temp > 0)
  500. uevent_notify(cm, "OVERHEAT");
  501. else
  502. uevent_notify(cm, "COLD");
  503. }
  504. /*
  505. * Check whole charging duration and discharing duration
  506. * after full-batt.
  507. */
  508. } else if (!cm->emergency_stop && check_charging_duration(cm)) {
  509. dev_dbg(cm->dev,
  510. "Charging/Discharging duration is out of range");
  511. /*
  512. * Check dropped voltage of battery. If battery voltage is more
  513. * dropped than fullbatt_vchkdrop_uV after fully charged state,
  514. * charger-manager have to recharge battery.
  515. */
  516. } else if (!cm->emergency_stop && is_ext_pwr_online(cm) &&
  517. !cm->charger_enabled) {
  518. fullbatt_vchk(&cm->fullbatt_vchk_work.work);
  519. /*
  520. * Check whether fully charged state to protect overcharge
  521. * if charger-manager is charging for battery.
  522. */
  523. } else if (!cm->emergency_stop && is_full_charged(cm) &&
  524. cm->charger_enabled) {
  525. dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n");
  526. uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]);
  527. try_charger_enable(cm, false);
  528. fullbatt_vchk(&cm->fullbatt_vchk_work.work);
  529. } else {
  530. cm->emergency_stop = 0;
  531. if (is_ext_pwr_online(cm)) {
  532. if (!try_charger_enable(cm, true))
  533. uevent_notify(cm, "CHARGING");
  534. }
  535. }
  536. return true;
  537. }
  538. /**
  539. * cm_monitor - Monitor every battery.
  540. *
  541. * Returns true if there is an event to notify from any of the batteries.
  542. * (True if the status of "emergency_stop" changes)
  543. */
  544. static bool cm_monitor(void)
  545. {
  546. bool stop = false;
  547. struct charger_manager *cm;
  548. mutex_lock(&cm_list_mtx);
  549. list_for_each_entry(cm, &cm_list, entry) {
  550. if (_cm_monitor(cm))
  551. stop = true;
  552. }
  553. mutex_unlock(&cm_list_mtx);
  554. return stop;
  555. }
  556. /**
  557. * _setup_polling - Setup the next instance of polling.
  558. * @work: work_struct of the function _setup_polling.
  559. */
  560. static void _setup_polling(struct work_struct *work)
  561. {
  562. unsigned long min = ULONG_MAX;
  563. struct charger_manager *cm;
  564. bool keep_polling = false;
  565. unsigned long _next_polling;
  566. mutex_lock(&cm_list_mtx);
  567. list_for_each_entry(cm, &cm_list, entry) {
  568. if (is_polling_required(cm) && cm->desc->polling_interval_ms) {
  569. keep_polling = true;
  570. if (min > cm->desc->polling_interval_ms)
  571. min = cm->desc->polling_interval_ms;
  572. }
  573. }
  574. polling_jiffy = msecs_to_jiffies(min);
  575. if (polling_jiffy <= CM_JIFFIES_SMALL)
  576. polling_jiffy = CM_JIFFIES_SMALL + 1;
  577. if (!keep_polling)
  578. polling_jiffy = ULONG_MAX;
  579. if (polling_jiffy == ULONG_MAX)
  580. goto out;
  581. WARN(cm_wq == NULL, "charger-manager: workqueue not initialized"
  582. ". try it later. %s\n", __func__);
  583. _next_polling = jiffies + polling_jiffy;
  584. if (!delayed_work_pending(&cm_monitor_work) ||
  585. (delayed_work_pending(&cm_monitor_work) &&
  586. time_after(next_polling, _next_polling))) {
  587. next_polling = jiffies + polling_jiffy;
  588. mod_delayed_work(cm_wq, &cm_monitor_work, polling_jiffy);
  589. }
  590. out:
  591. mutex_unlock(&cm_list_mtx);
  592. }
  593. static DECLARE_WORK(setup_polling, _setup_polling);
  594. /**
  595. * cm_monitor_poller - The Monitor / Poller.
  596. * @work: work_struct of the function cm_monitor_poller
  597. *
  598. * During non-suspended state, cm_monitor_poller is used to poll and monitor
  599. * the batteries.
  600. */
  601. static void cm_monitor_poller(struct work_struct *work)
  602. {
  603. cm_monitor();
  604. schedule_work(&setup_polling);
  605. }
  606. /**
  607. * fullbatt_handler - Event handler for CM_EVENT_BATT_FULL
  608. * @cm: the Charger Manager representing the battery.
  609. */
  610. static void fullbatt_handler(struct charger_manager *cm)
  611. {
  612. struct charger_desc *desc = cm->desc;
  613. if (!desc->fullbatt_vchkdrop_uV || !desc->fullbatt_vchkdrop_ms)
  614. goto out;
  615. if (cm_suspended)
  616. device_set_wakeup_capable(cm->dev, true);
  617. mod_delayed_work(cm_wq, &cm->fullbatt_vchk_work,
  618. msecs_to_jiffies(desc->fullbatt_vchkdrop_ms));
  619. cm->fullbatt_vchk_jiffies_at = jiffies + msecs_to_jiffies(
  620. desc->fullbatt_vchkdrop_ms);
  621. if (cm->fullbatt_vchk_jiffies_at == 0)
  622. cm->fullbatt_vchk_jiffies_at = 1;
  623. out:
  624. dev_info(cm->dev, "EVENT_HANDLE: Battery Fully Charged.\n");
  625. uevent_notify(cm, default_event_names[CM_EVENT_BATT_FULL]);
  626. }
  627. /**
  628. * battout_handler - Event handler for CM_EVENT_BATT_OUT
  629. * @cm: the Charger Manager representing the battery.
  630. */
  631. static void battout_handler(struct charger_manager *cm)
  632. {
  633. if (cm_suspended)
  634. device_set_wakeup_capable(cm->dev, true);
  635. if (!is_batt_present(cm)) {
  636. dev_emerg(cm->dev, "Battery Pulled Out!\n");
  637. uevent_notify(cm, default_event_names[CM_EVENT_BATT_OUT]);
  638. } else {
  639. uevent_notify(cm, "Battery Reinserted?");
  640. }
  641. }
  642. /**
  643. * misc_event_handler - Handler for other evnets
  644. * @cm: the Charger Manager representing the battery.
  645. * @type: the Charger Manager representing the battery.
  646. */
  647. static void misc_event_handler(struct charger_manager *cm,
  648. enum cm_event_types type)
  649. {
  650. if (cm_suspended)
  651. device_set_wakeup_capable(cm->dev, true);
  652. if (!delayed_work_pending(&cm_monitor_work) &&
  653. is_polling_required(cm) && cm->desc->polling_interval_ms)
  654. schedule_work(&setup_polling);
  655. uevent_notify(cm, default_event_names[type]);
  656. }
  657. static int charger_get_property(struct power_supply *psy,
  658. enum power_supply_property psp,
  659. union power_supply_propval *val)
  660. {
  661. struct charger_manager *cm = container_of(psy,
  662. struct charger_manager, charger_psy);
  663. struct charger_desc *desc = cm->desc;
  664. int ret = 0;
  665. int uV;
  666. switch (psp) {
  667. case POWER_SUPPLY_PROP_STATUS:
  668. if (is_charging(cm))
  669. val->intval = POWER_SUPPLY_STATUS_CHARGING;
  670. else if (is_ext_pwr_online(cm))
  671. val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
  672. else
  673. val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
  674. break;
  675. case POWER_SUPPLY_PROP_HEALTH:
  676. if (cm->emergency_stop > 0)
  677. val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
  678. else if (cm->emergency_stop < 0)
  679. val->intval = POWER_SUPPLY_HEALTH_COLD;
  680. else
  681. val->intval = POWER_SUPPLY_HEALTH_GOOD;
  682. break;
  683. case POWER_SUPPLY_PROP_PRESENT:
  684. if (is_batt_present(cm))
  685. val->intval = 1;
  686. else
  687. val->intval = 0;
  688. break;
  689. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  690. ret = get_batt_uV(cm, &val->intval);
  691. break;
  692. case POWER_SUPPLY_PROP_CURRENT_NOW:
  693. ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
  694. POWER_SUPPLY_PROP_CURRENT_NOW, val);
  695. break;
  696. case POWER_SUPPLY_PROP_TEMP:
  697. /* in thenth of centigrade */
  698. if (cm->last_temp_mC == INT_MIN)
  699. desc->temperature_out_of_range(&cm->last_temp_mC);
  700. val->intval = cm->last_temp_mC / 100;
  701. if (!desc->measure_battery_temp)
  702. ret = -ENODEV;
  703. break;
  704. case POWER_SUPPLY_PROP_TEMP_AMBIENT:
  705. /* in thenth of centigrade */
  706. if (cm->last_temp_mC == INT_MIN)
  707. desc->temperature_out_of_range(&cm->last_temp_mC);
  708. val->intval = cm->last_temp_mC / 100;
  709. if (desc->measure_battery_temp)
  710. ret = -ENODEV;
  711. break;
  712. case POWER_SUPPLY_PROP_CAPACITY:
  713. if (!cm->fuel_gauge) {
  714. ret = -ENODEV;
  715. break;
  716. }
  717. if (!is_batt_present(cm)) {
  718. /* There is no battery. Assume 100% */
  719. val->intval = 100;
  720. break;
  721. }
  722. ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
  723. POWER_SUPPLY_PROP_CAPACITY, val);
  724. if (ret)
  725. break;
  726. if (val->intval > 100) {
  727. val->intval = 100;
  728. break;
  729. }
  730. if (val->intval < 0)
  731. val->intval = 0;
  732. /* Do not adjust SOC when charging: voltage is overrated */
  733. if (is_charging(cm))
  734. break;
  735. /*
  736. * If the capacity value is inconsistent, calibrate it base on
  737. * the battery voltage values and the thresholds given as desc
  738. */
  739. ret = get_batt_uV(cm, &uV);
  740. if (ret) {
  741. /* Voltage information not available. No calibration */
  742. ret = 0;
  743. break;
  744. }
  745. if (desc->fullbatt_uV > 0 && uV >= desc->fullbatt_uV &&
  746. !is_charging(cm)) {
  747. val->intval = 100;
  748. break;
  749. }
  750. break;
  751. case POWER_SUPPLY_PROP_ONLINE:
  752. if (is_ext_pwr_online(cm))
  753. val->intval = 1;
  754. else
  755. val->intval = 0;
  756. break;
  757. case POWER_SUPPLY_PROP_CHARGE_FULL:
  758. if (is_full_charged(cm))
  759. val->intval = 1;
  760. else
  761. val->intval = 0;
  762. ret = 0;
  763. break;
  764. case POWER_SUPPLY_PROP_CHARGE_NOW:
  765. if (is_charging(cm)) {
  766. ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
  767. POWER_SUPPLY_PROP_CHARGE_NOW,
  768. val);
  769. if (ret) {
  770. val->intval = 1;
  771. ret = 0;
  772. } else {
  773. /* If CHARGE_NOW is supplied, use it */
  774. val->intval = (val->intval > 0) ?
  775. val->intval : 1;
  776. }
  777. } else {
  778. val->intval = 0;
  779. }
  780. break;
  781. default:
  782. return -EINVAL;
  783. }
  784. return ret;
  785. }
  786. #define NUM_CHARGER_PSY_OPTIONAL (4)
  787. static enum power_supply_property default_charger_props[] = {
  788. /* Guaranteed to provide */
  789. POWER_SUPPLY_PROP_STATUS,
  790. POWER_SUPPLY_PROP_HEALTH,
  791. POWER_SUPPLY_PROP_PRESENT,
  792. POWER_SUPPLY_PROP_VOLTAGE_NOW,
  793. POWER_SUPPLY_PROP_CAPACITY,
  794. POWER_SUPPLY_PROP_ONLINE,
  795. POWER_SUPPLY_PROP_CHARGE_FULL,
  796. /*
  797. * Optional properties are:
  798. * POWER_SUPPLY_PROP_CHARGE_NOW,
  799. * POWER_SUPPLY_PROP_CURRENT_NOW,
  800. * POWER_SUPPLY_PROP_TEMP, and
  801. * POWER_SUPPLY_PROP_TEMP_AMBIENT,
  802. */
  803. };
  804. static struct power_supply psy_default = {
  805. .name = "battery",
  806. .type = POWER_SUPPLY_TYPE_BATTERY,
  807. .properties = default_charger_props,
  808. .num_properties = ARRAY_SIZE(default_charger_props),
  809. .get_property = charger_get_property,
  810. };
  811. /**
  812. * cm_setup_timer - For in-suspend monitoring setup wakeup alarm
  813. * for suspend_again.
  814. *
  815. * Returns true if the alarm is set for Charger Manager to use.
  816. * Returns false if
  817. * cm_setup_timer fails to set an alarm,
  818. * cm_setup_timer does not need to set an alarm for Charger Manager,
  819. * or an alarm previously configured is to be used.
  820. */
  821. static bool cm_setup_timer(void)
  822. {
  823. struct charger_manager *cm;
  824. unsigned int wakeup_ms = UINT_MAX;
  825. bool ret = false;
  826. mutex_lock(&cm_list_mtx);
  827. list_for_each_entry(cm, &cm_list, entry) {
  828. unsigned int fbchk_ms = 0;
  829. /* fullbatt_vchk is required. setup timer for that */
  830. if (cm->fullbatt_vchk_jiffies_at) {
  831. fbchk_ms = jiffies_to_msecs(cm->fullbatt_vchk_jiffies_at
  832. - jiffies);
  833. if (time_is_before_eq_jiffies(
  834. cm->fullbatt_vchk_jiffies_at) ||
  835. msecs_to_jiffies(fbchk_ms) < CM_JIFFIES_SMALL) {
  836. fullbatt_vchk(&cm->fullbatt_vchk_work.work);
  837. fbchk_ms = 0;
  838. }
  839. }
  840. CM_MIN_VALID(wakeup_ms, fbchk_ms);
  841. /* Skip if polling is not required for this CM */
  842. if (!is_polling_required(cm) && !cm->emergency_stop)
  843. continue;
  844. if (cm->desc->polling_interval_ms == 0)
  845. continue;
  846. CM_MIN_VALID(wakeup_ms, cm->desc->polling_interval_ms);
  847. }
  848. mutex_unlock(&cm_list_mtx);
  849. if (wakeup_ms < UINT_MAX && wakeup_ms > 0) {
  850. pr_info("Charger Manager wakeup timer: %u ms.\n", wakeup_ms);
  851. if (rtc_dev) {
  852. struct rtc_wkalrm tmp;
  853. unsigned long time, now;
  854. unsigned long add = DIV_ROUND_UP(wakeup_ms, 1000);
  855. /*
  856. * Set alarm with the polling interval (wakeup_ms)
  857. * except when rtc_wkalarm_save comes first.
  858. * However, the alarm time should be NOW +
  859. * CM_RTC_SMALL or later.
  860. */
  861. tmp.enabled = 1;
  862. rtc_read_time(rtc_dev, &tmp.time);
  863. rtc_tm_to_time(&tmp.time, &now);
  864. if (add < CM_RTC_SMALL)
  865. add = CM_RTC_SMALL;
  866. time = now + add;
  867. ret = true;
  868. if (rtc_wkalarm_save.enabled &&
  869. rtc_wkalarm_save_time &&
  870. rtc_wkalarm_save_time < time) {
  871. if (rtc_wkalarm_save_time < now + CM_RTC_SMALL)
  872. time = now + CM_RTC_SMALL;
  873. else
  874. time = rtc_wkalarm_save_time;
  875. /* The timer is not appointed by CM */
  876. ret = false;
  877. }
  878. pr_info("Waking up after %lu secs.\n",
  879. time - now);
  880. rtc_time_to_tm(time, &tmp.time);
  881. rtc_set_alarm(rtc_dev, &tmp);
  882. cm_suspend_duration_ms += wakeup_ms;
  883. return ret;
  884. }
  885. }
  886. if (rtc_dev)
  887. rtc_set_alarm(rtc_dev, &rtc_wkalarm_save);
  888. return false;
  889. }
  890. static void _cm_fbchk_in_suspend(struct charger_manager *cm)
  891. {
  892. unsigned long jiffy_now = jiffies;
  893. if (!cm->fullbatt_vchk_jiffies_at)
  894. return;
  895. if (g_desc && g_desc->assume_timer_stops_in_suspend)
  896. jiffy_now += msecs_to_jiffies(cm_suspend_duration_ms);
  897. /* Execute now if it's going to be executed not too long after */
  898. jiffy_now += CM_JIFFIES_SMALL;
  899. if (time_after_eq(jiffy_now, cm->fullbatt_vchk_jiffies_at))
  900. fullbatt_vchk(&cm->fullbatt_vchk_work.work);
  901. }
  902. /**
  903. * cm_suspend_again - Determine whether suspend again or not
  904. *
  905. * Returns true if the system should be suspended again
  906. * Returns false if the system should be woken up
  907. */
  908. bool cm_suspend_again(void)
  909. {
  910. struct charger_manager *cm;
  911. bool ret = false;
  912. if (!g_desc || !g_desc->rtc_only_wakeup || !g_desc->rtc_only_wakeup() ||
  913. !cm_rtc_set)
  914. return false;
  915. if (cm_monitor())
  916. goto out;
  917. ret = true;
  918. mutex_lock(&cm_list_mtx);
  919. list_for_each_entry(cm, &cm_list, entry) {
  920. _cm_fbchk_in_suspend(cm);
  921. if (cm->status_save_ext_pwr_inserted != is_ext_pwr_online(cm) ||
  922. cm->status_save_batt != is_batt_present(cm)) {
  923. ret = false;
  924. break;
  925. }
  926. }
  927. mutex_unlock(&cm_list_mtx);
  928. cm_rtc_set = cm_setup_timer();
  929. out:
  930. /* It's about the time when the non-CM appointed timer goes off */
  931. if (rtc_wkalarm_save.enabled) {
  932. unsigned long now;
  933. struct rtc_time tmp;
  934. rtc_read_time(rtc_dev, &tmp);
  935. rtc_tm_to_time(&tmp, &now);
  936. if (rtc_wkalarm_save_time &&
  937. now + CM_RTC_SMALL >= rtc_wkalarm_save_time)
  938. return false;
  939. }
  940. return ret;
  941. }
  942. EXPORT_SYMBOL_GPL(cm_suspend_again);
  943. /**
  944. * setup_charger_manager - initialize charger_global_desc data
  945. * @gd: pointer to instance of charger_global_desc
  946. */
  947. int setup_charger_manager(struct charger_global_desc *gd)
  948. {
  949. if (!gd)
  950. return -EINVAL;
  951. if (rtc_dev)
  952. rtc_class_close(rtc_dev);
  953. rtc_dev = NULL;
  954. g_desc = NULL;
  955. if (!gd->rtc_only_wakeup) {
  956. pr_err("The callback rtc_only_wakeup is not given.\n");
  957. return -EINVAL;
  958. }
  959. if (gd->rtc_name) {
  960. rtc_dev = rtc_class_open(gd->rtc_name);
  961. if (IS_ERR_OR_NULL(rtc_dev)) {
  962. rtc_dev = NULL;
  963. /* Retry at probe. RTC may be not registered yet */
  964. }
  965. } else {
  966. pr_warn("No wakeup timer is given for charger manager."
  967. "In-suspend monitoring won't work.\n");
  968. }
  969. g_desc = gd;
  970. return 0;
  971. }
  972. EXPORT_SYMBOL_GPL(setup_charger_manager);
  973. /**
  974. * charger_extcon_work - enable/diable charger according to the state
  975. * of charger cable
  976. *
  977. * @work: work_struct of the function charger_extcon_work.
  978. */
  979. static void charger_extcon_work(struct work_struct *work)
  980. {
  981. struct charger_cable *cable =
  982. container_of(work, struct charger_cable, wq);
  983. int ret;
  984. if (cable->attached && cable->min_uA != 0 && cable->max_uA != 0) {
  985. ret = regulator_set_current_limit(cable->charger->consumer,
  986. cable->min_uA, cable->max_uA);
  987. if (ret < 0) {
  988. pr_err("Cannot set current limit of %s (%s)\n",
  989. cable->charger->regulator_name, cable->name);
  990. return;
  991. }
  992. pr_info("Set current limit of %s : %duA ~ %duA\n",
  993. cable->charger->regulator_name,
  994. cable->min_uA, cable->max_uA);
  995. }
  996. try_charger_enable(cable->cm, cable->attached);
  997. }
  998. /**
  999. * charger_extcon_notifier - receive the state of charger cable
  1000. * when registered cable is attached or detached.
  1001. *
  1002. * @self: the notifier block of the charger_extcon_notifier.
  1003. * @event: the cable state.
  1004. * @ptr: the data pointer of notifier block.
  1005. */
  1006. static int charger_extcon_notifier(struct notifier_block *self,
  1007. unsigned long event, void *ptr)
  1008. {
  1009. struct charger_cable *cable =
  1010. container_of(self, struct charger_cable, nb);
  1011. /*
  1012. * The newly state of charger cable.
  1013. * If cable is attached, cable->attached is true.
  1014. */
  1015. cable->attached = event;
  1016. /*
  1017. * Setup monitoring to check battery state
  1018. * when charger cable is attached.
  1019. */
  1020. if (cable->attached && is_polling_required(cable->cm)) {
  1021. if (work_pending(&setup_polling))
  1022. cancel_work_sync(&setup_polling);
  1023. schedule_work(&setup_polling);
  1024. }
  1025. /*
  1026. * Setup work for controlling charger(regulator)
  1027. * according to charger cable.
  1028. */
  1029. schedule_work(&cable->wq);
  1030. return NOTIFY_DONE;
  1031. }
  1032. /**
  1033. * charger_extcon_init - register external connector to use it
  1034. * as the charger cable
  1035. *
  1036. * @cm: the Charger Manager representing the battery.
  1037. * @cable: the Charger cable representing the external connector.
  1038. */
  1039. static int charger_extcon_init(struct charger_manager *cm,
  1040. struct charger_cable *cable)
  1041. {
  1042. int ret = 0;
  1043. /*
  1044. * Charger manager use Extcon framework to identify
  1045. * the charger cable among various external connector
  1046. * cable (e.g., TA, USB, MHL, Dock).
  1047. */
  1048. INIT_WORK(&cable->wq, charger_extcon_work);
  1049. cable->nb.notifier_call = charger_extcon_notifier;
  1050. ret = extcon_register_interest(&cable->extcon_dev,
  1051. cable->extcon_name, cable->name, &cable->nb);
  1052. if (ret < 0) {
  1053. pr_info("Cannot register extcon_dev for %s(cable: %s).\n",
  1054. cable->extcon_name,
  1055. cable->name);
  1056. ret = -EINVAL;
  1057. }
  1058. return ret;
  1059. }
  1060. /* help function of sysfs node to control charger(regulator) */
  1061. static ssize_t charger_name_show(struct device *dev,
  1062. struct device_attribute *attr, char *buf)
  1063. {
  1064. struct charger_regulator *charger
  1065. = container_of(attr, struct charger_regulator, attr_name);
  1066. return sprintf(buf, "%s\n", charger->regulator_name);
  1067. }
  1068. static ssize_t charger_state_show(struct device *dev,
  1069. struct device_attribute *attr, char *buf)
  1070. {
  1071. struct charger_regulator *charger
  1072. = container_of(attr, struct charger_regulator, attr_state);
  1073. int state = 0;
  1074. if (!charger->externally_control)
  1075. state = regulator_is_enabled(charger->consumer);
  1076. return sprintf(buf, "%s\n", state ? "enabled" : "disabled");
  1077. }
  1078. static ssize_t charger_externally_control_show(struct device *dev,
  1079. struct device_attribute *attr, char *buf)
  1080. {
  1081. struct charger_regulator *charger = container_of(attr,
  1082. struct charger_regulator, attr_externally_control);
  1083. return sprintf(buf, "%d\n", charger->externally_control);
  1084. }
  1085. static ssize_t charger_externally_control_store(struct device *dev,
  1086. struct device_attribute *attr, const char *buf,
  1087. size_t count)
  1088. {
  1089. struct charger_regulator *charger
  1090. = container_of(attr, struct charger_regulator,
  1091. attr_externally_control);
  1092. struct charger_manager *cm = charger->cm;
  1093. struct charger_desc *desc = cm->desc;
  1094. int i;
  1095. int ret;
  1096. int externally_control;
  1097. int chargers_externally_control = 1;
  1098. ret = sscanf(buf, "%d", &externally_control);
  1099. if (ret == 0) {
  1100. ret = -EINVAL;
  1101. return ret;
  1102. }
  1103. if (!externally_control) {
  1104. charger->externally_control = 0;
  1105. return count;
  1106. }
  1107. for (i = 0; i < desc->num_charger_regulators; i++) {
  1108. if (&desc->charger_regulators[i] != charger &&
  1109. !desc->charger_regulators[i].externally_control) {
  1110. /*
  1111. * At least, one charger is controlled by
  1112. * charger-manager
  1113. */
  1114. chargers_externally_control = 0;
  1115. break;
  1116. }
  1117. }
  1118. if (!chargers_externally_control) {
  1119. if (cm->charger_enabled) {
  1120. try_charger_enable(charger->cm, false);
  1121. charger->externally_control = externally_control;
  1122. try_charger_enable(charger->cm, true);
  1123. } else {
  1124. charger->externally_control = externally_control;
  1125. }
  1126. } else {
  1127. dev_warn(cm->dev,
  1128. "'%s' regulator should be controlled "
  1129. "in charger-manager because charger-manager "
  1130. "must need at least one charger for charging\n",
  1131. charger->regulator_name);
  1132. }
  1133. return count;
  1134. }
  1135. static int charger_manager_probe(struct platform_device *pdev)
  1136. {
  1137. struct charger_desc *desc = dev_get_platdata(&pdev->dev);
  1138. struct charger_manager *cm;
  1139. int ret = 0, i = 0;
  1140. int j = 0;
  1141. int chargers_externally_control = 1;
  1142. union power_supply_propval val;
  1143. if (g_desc && !rtc_dev && g_desc->rtc_name) {
  1144. rtc_dev = rtc_class_open(g_desc->rtc_name);
  1145. if (IS_ERR_OR_NULL(rtc_dev)) {
  1146. rtc_dev = NULL;
  1147. dev_err(&pdev->dev, "Cannot get RTC %s.\n",
  1148. g_desc->rtc_name);
  1149. ret = -ENODEV;
  1150. goto err_alloc;
  1151. }
  1152. }
  1153. if (!desc) {
  1154. dev_err(&pdev->dev, "No platform data (desc) found.\n");
  1155. ret = -ENODEV;
  1156. goto err_alloc;
  1157. }
  1158. cm = kzalloc(sizeof(struct charger_manager), GFP_KERNEL);
  1159. if (!cm) {
  1160. dev_err(&pdev->dev, "Cannot allocate memory.\n");
  1161. ret = -ENOMEM;
  1162. goto err_alloc;
  1163. }
  1164. /* Basic Values. Unspecified are Null or 0 */
  1165. cm->dev = &pdev->dev;
  1166. cm->desc = kzalloc(sizeof(struct charger_desc), GFP_KERNEL);
  1167. if (!cm->desc) {
  1168. dev_err(&pdev->dev, "Cannot allocate memory.\n");
  1169. ret = -ENOMEM;
  1170. goto err_alloc_desc;
  1171. }
  1172. memcpy(cm->desc, desc, sizeof(struct charger_desc));
  1173. cm->last_temp_mC = INT_MIN; /* denotes "unmeasured, yet" */
  1174. /*
  1175. * The following two do not need to be errors.
  1176. * Users may intentionally ignore those two features.
  1177. */
  1178. if (desc->fullbatt_uV == 0) {
  1179. dev_info(&pdev->dev, "Ignoring full-battery voltage threshold"
  1180. " as it is not supplied.");
  1181. }
  1182. if (!desc->fullbatt_vchkdrop_ms || !desc->fullbatt_vchkdrop_uV) {
  1183. dev_info(&pdev->dev, "Disabling full-battery voltage drop "
  1184. "checking mechanism as it is not supplied.");
  1185. desc->fullbatt_vchkdrop_ms = 0;
  1186. desc->fullbatt_vchkdrop_uV = 0;
  1187. }
  1188. if (desc->fullbatt_soc == 0) {
  1189. dev_info(&pdev->dev, "Ignoring full-battery soc(state of"
  1190. " charge) threshold as it is not"
  1191. " supplied.");
  1192. }
  1193. if (desc->fullbatt_full_capacity == 0) {
  1194. dev_info(&pdev->dev, "Ignoring full-battery full capacity"
  1195. " threshold as it is not supplied.");
  1196. }
  1197. if (!desc->charger_regulators || desc->num_charger_regulators < 1) {
  1198. ret = -EINVAL;
  1199. dev_err(&pdev->dev, "charger_regulators undefined.\n");
  1200. goto err_no_charger;
  1201. }
  1202. if (!desc->psy_charger_stat || !desc->psy_charger_stat[0]) {
  1203. dev_err(&pdev->dev, "No power supply defined.\n");
  1204. ret = -EINVAL;
  1205. goto err_no_charger_stat;
  1206. }
  1207. /* Counting index only */
  1208. while (desc->psy_charger_stat[i])
  1209. i++;
  1210. cm->charger_stat = kzalloc(sizeof(struct power_supply *) * (i + 1),
  1211. GFP_KERNEL);
  1212. if (!cm->charger_stat) {
  1213. ret = -ENOMEM;
  1214. goto err_no_charger_stat;
  1215. }
  1216. for (i = 0; desc->psy_charger_stat[i]; i++) {
  1217. cm->charger_stat[i] = power_supply_get_by_name(
  1218. desc->psy_charger_stat[i]);
  1219. if (!cm->charger_stat[i]) {
  1220. dev_err(&pdev->dev, "Cannot find power supply "
  1221. "\"%s\"\n",
  1222. desc->psy_charger_stat[i]);
  1223. ret = -ENODEV;
  1224. goto err_chg_stat;
  1225. }
  1226. }
  1227. cm->fuel_gauge = power_supply_get_by_name(desc->psy_fuel_gauge);
  1228. if (!cm->fuel_gauge) {
  1229. dev_err(&pdev->dev, "Cannot find power supply \"%s\"\n",
  1230. desc->psy_fuel_gauge);
  1231. ret = -ENODEV;
  1232. goto err_chg_stat;
  1233. }
  1234. if (desc->polling_interval_ms == 0 ||
  1235. msecs_to_jiffies(desc->polling_interval_ms) <= CM_JIFFIES_SMALL) {
  1236. dev_err(&pdev->dev, "polling_interval_ms is too small\n");
  1237. ret = -EINVAL;
  1238. goto err_chg_stat;
  1239. }
  1240. if (!desc->temperature_out_of_range) {
  1241. dev_err(&pdev->dev, "there is no temperature_out_of_range\n");
  1242. ret = -EINVAL;
  1243. goto err_chg_stat;
  1244. }
  1245. if (!desc->charging_max_duration_ms ||
  1246. !desc->discharging_max_duration_ms) {
  1247. dev_info(&pdev->dev, "Cannot limit charging duration "
  1248. "checking mechanism to prevent overcharge/overheat "
  1249. "and control discharging duration");
  1250. desc->charging_max_duration_ms = 0;
  1251. desc->discharging_max_duration_ms = 0;
  1252. }
  1253. platform_set_drvdata(pdev, cm);
  1254. memcpy(&cm->charger_psy, &psy_default, sizeof(psy_default));
  1255. if (!desc->psy_name) {
  1256. strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX);
  1257. } else {
  1258. strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX);
  1259. }
  1260. cm->charger_psy.name = cm->psy_name_buf;
  1261. /* Allocate for psy properties because they may vary */
  1262. cm->charger_psy.properties = kzalloc(sizeof(enum power_supply_property)
  1263. * (ARRAY_SIZE(default_charger_props) +
  1264. NUM_CHARGER_PSY_OPTIONAL),
  1265. GFP_KERNEL);
  1266. if (!cm->charger_psy.properties) {
  1267. dev_err(&pdev->dev, "Cannot allocate for psy properties.\n");
  1268. ret = -ENOMEM;
  1269. goto err_chg_stat;
  1270. }
  1271. memcpy(cm->charger_psy.properties, default_charger_props,
  1272. sizeof(enum power_supply_property) *
  1273. ARRAY_SIZE(default_charger_props));
  1274. cm->charger_psy.num_properties = psy_default.num_properties;
  1275. /* Find which optional psy-properties are available */
  1276. if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
  1277. POWER_SUPPLY_PROP_CHARGE_NOW, &val)) {
  1278. cm->charger_psy.properties[cm->charger_psy.num_properties] =
  1279. POWER_SUPPLY_PROP_CHARGE_NOW;
  1280. cm->charger_psy.num_properties++;
  1281. }
  1282. if (!cm->fuel_gauge->get_property(cm->fuel_gauge,
  1283. POWER_SUPPLY_PROP_CURRENT_NOW,
  1284. &val)) {
  1285. cm->charger_psy.properties[cm->charger_psy.num_properties] =
  1286. POWER_SUPPLY_PROP_CURRENT_NOW;
  1287. cm->charger_psy.num_properties++;
  1288. }
  1289. if (desc->measure_battery_temp) {
  1290. cm->charger_psy.properties[cm->charger_psy.num_properties] =
  1291. POWER_SUPPLY_PROP_TEMP;
  1292. cm->charger_psy.num_properties++;
  1293. } else {
  1294. cm->charger_psy.properties[cm->charger_psy.num_properties] =
  1295. POWER_SUPPLY_PROP_TEMP_AMBIENT;
  1296. cm->charger_psy.num_properties++;
  1297. }
  1298. INIT_DELAYED_WORK(&cm->fullbatt_vchk_work, fullbatt_vchk);
  1299. ret = power_supply_register(NULL, &cm->charger_psy);
  1300. if (ret) {
  1301. dev_err(&pdev->dev, "Cannot register charger-manager with"
  1302. " name \"%s\".\n", cm->charger_psy.name);
  1303. goto err_register;
  1304. }
  1305. for (i = 0 ; i < desc->num_charger_regulators ; i++) {
  1306. struct charger_regulator *charger
  1307. = &desc->charger_regulators[i];
  1308. char buf[11];
  1309. char *str;
  1310. charger->consumer = regulator_get(&pdev->dev,
  1311. charger->regulator_name);
  1312. if (charger->consumer == NULL) {
  1313. dev_err(&pdev->dev, "Cannot find charger(%s)n",
  1314. charger->regulator_name);
  1315. ret = -EINVAL;
  1316. goto err_chg_get;
  1317. }
  1318. charger->cm = cm;
  1319. for (j = 0 ; j < charger->num_cables ; j++) {
  1320. struct charger_cable *cable = &charger->cables[j];
  1321. ret = charger_extcon_init(cm, cable);
  1322. if (ret < 0) {
  1323. dev_err(&pdev->dev, "Cannot find charger(%s)n",
  1324. charger->regulator_name);
  1325. goto err_extcon;
  1326. }
  1327. cable->charger = charger;
  1328. cable->cm = cm;
  1329. }
  1330. /* Create sysfs entry to control charger(regulator) */
  1331. snprintf(buf, 10, "charger.%d", i);
  1332. str = kzalloc(sizeof(char) * (strlen(buf) + 1), GFP_KERNEL);
  1333. if (!str) {
  1334. for (i--; i >= 0; i--) {
  1335. charger = &desc->charger_regulators[i];
  1336. kfree(charger->attr_g.name);
  1337. }
  1338. ret = -ENOMEM;
  1339. goto err_extcon;
  1340. }
  1341. strcpy(str, buf);
  1342. charger->attrs[0] = &charger->attr_name.attr;
  1343. charger->attrs[1] = &charger->attr_state.attr;
  1344. charger->attrs[2] = &charger->attr_externally_control.attr;
  1345. charger->attrs[3] = NULL;
  1346. charger->attr_g.name = str;
  1347. charger->attr_g.attrs = charger->attrs;
  1348. sysfs_attr_init(&charger->attr_name.attr);
  1349. charger->attr_name.attr.name = "name";
  1350. charger->attr_name.attr.mode = 0444;
  1351. charger->attr_name.show = charger_name_show;
  1352. sysfs_attr_init(&charger->attr_state.attr);
  1353. charger->attr_state.attr.name = "state";
  1354. charger->attr_state.attr.mode = 0444;
  1355. charger->attr_state.show = charger_state_show;
  1356. sysfs_attr_init(&charger->attr_externally_control.attr);
  1357. charger->attr_externally_control.attr.name
  1358. = "externally_control";
  1359. charger->attr_externally_control.attr.mode = 0644;
  1360. charger->attr_externally_control.show
  1361. = charger_externally_control_show;
  1362. charger->attr_externally_control.store
  1363. = charger_externally_control_store;
  1364. if (!desc->charger_regulators[i].externally_control ||
  1365. !chargers_externally_control) {
  1366. chargers_externally_control = 0;
  1367. }
  1368. dev_info(&pdev->dev, "'%s' regulator's externally_control"
  1369. "is %d\n", charger->regulator_name,
  1370. charger->externally_control);
  1371. ret = sysfs_create_group(&cm->charger_psy.dev->kobj,
  1372. &charger->attr_g);
  1373. if (ret < 0) {
  1374. dev_info(&pdev->dev, "Cannot create sysfs entry"
  1375. "of %s regulator\n",
  1376. charger->regulator_name);
  1377. }
  1378. }
  1379. if (chargers_externally_control) {
  1380. dev_err(&pdev->dev, "Cannot register regulator because "
  1381. "charger-manager must need at least "
  1382. "one charger for charging battery\n");
  1383. ret = -EINVAL;
  1384. goto err_chg_enable;
  1385. }
  1386. ret = try_charger_enable(cm, true);
  1387. if (ret) {
  1388. dev_err(&pdev->dev, "Cannot enable charger regulators\n");
  1389. goto err_chg_enable;
  1390. }
  1391. /* Add to the list */
  1392. mutex_lock(&cm_list_mtx);
  1393. list_add(&cm->entry, &cm_list);
  1394. mutex_unlock(&cm_list_mtx);
  1395. /*
  1396. * Charger-manager is capable of waking up the systme from sleep
  1397. * when event is happend through cm_notify_event()
  1398. */
  1399. device_init_wakeup(&pdev->dev, true);
  1400. device_set_wakeup_capable(&pdev->dev, false);
  1401. schedule_work(&setup_polling);
  1402. return 0;
  1403. err_chg_enable:
  1404. for (i = 0; i < desc->num_charger_regulators; i++) {
  1405. struct charger_regulator *charger;
  1406. charger = &desc->charger_regulators[i];
  1407. sysfs_remove_group(&cm->charger_psy.dev->kobj,
  1408. &charger->attr_g);
  1409. kfree(charger->attr_g.name);
  1410. }
  1411. err_extcon:
  1412. for (i = 0 ; i < desc->num_charger_regulators ; i++) {
  1413. struct charger_regulator *charger
  1414. = &desc->charger_regulators[i];
  1415. for (j = 0 ; j < charger->num_cables ; j++) {
  1416. struct charger_cable *cable = &charger->cables[j];
  1417. extcon_unregister_interest(&cable->extcon_dev);
  1418. }
  1419. }
  1420. err_chg_get:
  1421. for (i = 0 ; i < desc->num_charger_regulators ; i++)
  1422. regulator_put(desc->charger_regulators[i].consumer);
  1423. power_supply_unregister(&cm->charger_psy);
  1424. err_register:
  1425. kfree(cm->charger_psy.properties);
  1426. err_chg_stat:
  1427. kfree(cm->charger_stat);
  1428. err_no_charger_stat:
  1429. err_no_charger:
  1430. kfree(cm->desc);
  1431. err_alloc_desc:
  1432. kfree(cm);
  1433. err_alloc:
  1434. return ret;
  1435. }
  1436. static int __devexit charger_manager_remove(struct platform_device *pdev)
  1437. {
  1438. struct charger_manager *cm = platform_get_drvdata(pdev);
  1439. struct charger_desc *desc = cm->desc;
  1440. int i = 0;
  1441. int j = 0;
  1442. /* Remove from the list */
  1443. mutex_lock(&cm_list_mtx);
  1444. list_del(&cm->entry);
  1445. mutex_unlock(&cm_list_mtx);
  1446. if (work_pending(&setup_polling))
  1447. cancel_work_sync(&setup_polling);
  1448. if (delayed_work_pending(&cm_monitor_work))
  1449. cancel_delayed_work_sync(&cm_monitor_work);
  1450. for (i = 0 ; i < desc->num_charger_regulators ; i++) {
  1451. struct charger_regulator *charger
  1452. = &desc->charger_regulators[i];
  1453. for (j = 0 ; j < charger->num_cables ; j++) {
  1454. struct charger_cable *cable = &charger->cables[j];
  1455. extcon_unregister_interest(&cable->extcon_dev);
  1456. }
  1457. }
  1458. for (i = 0 ; i < desc->num_charger_regulators ; i++)
  1459. regulator_put(desc->charger_regulators[i].consumer);
  1460. power_supply_unregister(&cm->charger_psy);
  1461. try_charger_enable(cm, false);
  1462. kfree(cm->charger_psy.properties);
  1463. kfree(cm->charger_stat);
  1464. kfree(cm->desc);
  1465. kfree(cm);
  1466. return 0;
  1467. }
  1468. static const struct platform_device_id charger_manager_id[] = {
  1469. { "charger-manager", 0 },
  1470. { },
  1471. };
  1472. MODULE_DEVICE_TABLE(platform, charger_manager_id);
  1473. static int cm_suspend_noirq(struct device *dev)
  1474. {
  1475. int ret = 0;
  1476. if (device_may_wakeup(dev)) {
  1477. device_set_wakeup_capable(dev, false);
  1478. ret = -EAGAIN;
  1479. }
  1480. return ret;
  1481. }
  1482. static int cm_suspend_prepare(struct device *dev)
  1483. {
  1484. struct charger_manager *cm = dev_get_drvdata(dev);
  1485. if (!cm_suspended) {
  1486. if (rtc_dev) {
  1487. struct rtc_time tmp;
  1488. unsigned long now;
  1489. rtc_read_alarm(rtc_dev, &rtc_wkalarm_save);
  1490. rtc_read_time(rtc_dev, &tmp);
  1491. if (rtc_wkalarm_save.enabled) {
  1492. rtc_tm_to_time(&rtc_wkalarm_save.time,
  1493. &rtc_wkalarm_save_time);
  1494. rtc_tm_to_time(&tmp, &now);
  1495. if (now > rtc_wkalarm_save_time)
  1496. rtc_wkalarm_save_time = 0;
  1497. } else {
  1498. rtc_wkalarm_save_time = 0;
  1499. }
  1500. }
  1501. cm_suspended = true;
  1502. }
  1503. if (delayed_work_pending(&cm->fullbatt_vchk_work))
  1504. cancel_delayed_work(&cm->fullbatt_vchk_work);
  1505. cm->status_save_ext_pwr_inserted = is_ext_pwr_online(cm);
  1506. cm->status_save_batt = is_batt_present(cm);
  1507. if (!cm_rtc_set) {
  1508. cm_suspend_duration_ms = 0;
  1509. cm_rtc_set = cm_setup_timer();
  1510. }
  1511. return 0;
  1512. }
  1513. static void cm_suspend_complete(struct device *dev)
  1514. {
  1515. struct charger_manager *cm = dev_get_drvdata(dev);
  1516. if (cm_suspended) {
  1517. if (rtc_dev) {
  1518. struct rtc_wkalrm tmp;
  1519. rtc_read_alarm(rtc_dev, &tmp);
  1520. rtc_wkalarm_save.pending = tmp.pending;
  1521. rtc_set_alarm(rtc_dev, &rtc_wkalarm_save);
  1522. }
  1523. cm_suspended = false;
  1524. cm_rtc_set = false;
  1525. }
  1526. /* Re-enqueue delayed work (fullbatt_vchk_work) */
  1527. if (cm->fullbatt_vchk_jiffies_at) {
  1528. unsigned long delay = 0;
  1529. unsigned long now = jiffies + CM_JIFFIES_SMALL;
  1530. if (time_after_eq(now, cm->fullbatt_vchk_jiffies_at)) {
  1531. delay = (unsigned long)((long)now
  1532. - (long)(cm->fullbatt_vchk_jiffies_at));
  1533. delay = jiffies_to_msecs(delay);
  1534. } else {
  1535. delay = 0;
  1536. }
  1537. /*
  1538. * Account for cm_suspend_duration_ms if
  1539. * assume_timer_stops_in_suspend is active
  1540. */
  1541. if (g_desc && g_desc->assume_timer_stops_in_suspend) {
  1542. if (delay > cm_suspend_duration_ms)
  1543. delay -= cm_suspend_duration_ms;
  1544. else
  1545. delay = 0;
  1546. }
  1547. queue_delayed_work(cm_wq, &cm->fullbatt_vchk_work,
  1548. msecs_to_jiffies(delay));
  1549. }
  1550. device_set_wakeup_capable(cm->dev, false);
  1551. uevent_notify(cm, NULL);
  1552. }
  1553. static const struct dev_pm_ops charger_manager_pm = {
  1554. .prepare = cm_suspend_prepare,
  1555. .suspend_noirq = cm_suspend_noirq,
  1556. .complete = cm_suspend_complete,
  1557. };
  1558. static struct platform_driver charger_manager_driver = {
  1559. .driver = {
  1560. .name = "charger-manager",
  1561. .owner = THIS_MODULE,
  1562. .pm = &charger_manager_pm,
  1563. },
  1564. .probe = charger_manager_probe,
  1565. .remove = __devexit_p(charger_manager_remove),
  1566. .id_table = charger_manager_id,
  1567. };
  1568. static int __init charger_manager_init(void)
  1569. {
  1570. cm_wq = create_freezable_workqueue("charger_manager");
  1571. INIT_DELAYED_WORK(&cm_monitor_work, cm_monitor_poller);
  1572. return platform_driver_register(&charger_manager_driver);
  1573. }
  1574. late_initcall(charger_manager_init);
  1575. static void __exit charger_manager_cleanup(void)
  1576. {
  1577. destroy_workqueue(cm_wq);
  1578. cm_wq = NULL;
  1579. platform_driver_unregister(&charger_manager_driver);
  1580. }
  1581. module_exit(charger_manager_cleanup);
  1582. /**
  1583. * find_power_supply - find the associated power_supply of charger
  1584. * @cm: the Charger Manager representing the battery
  1585. * @psy: pointer to instance of charger's power_supply
  1586. */
  1587. static bool find_power_supply(struct charger_manager *cm,
  1588. struct power_supply *psy)
  1589. {
  1590. int i;
  1591. bool found = false;
  1592. for (i = 0; cm->charger_stat[i]; i++) {
  1593. if (psy == cm->charger_stat[i]) {
  1594. found = true;
  1595. break;
  1596. }
  1597. }
  1598. return found;
  1599. }
  1600. /**
  1601. * cm_notify_event - charger driver notify Charger Manager of charger event
  1602. * @psy: pointer to instance of charger's power_supply
  1603. * @type: type of charger event
  1604. * @msg: optional message passed to uevent_notify fuction
  1605. */
  1606. void cm_notify_event(struct power_supply *psy, enum cm_event_types type,
  1607. char *msg)
  1608. {
  1609. struct charger_manager *cm;
  1610. bool found_power_supply = false;
  1611. if (psy == NULL)
  1612. return;
  1613. mutex_lock(&cm_list_mtx);
  1614. list_for_each_entry(cm, &cm_list, entry) {
  1615. found_power_supply = find_power_supply(cm, psy);
  1616. if (found_power_supply)
  1617. break;
  1618. }
  1619. mutex_unlock(&cm_list_mtx);
  1620. if (!found_power_supply)
  1621. return;
  1622. switch (type) {
  1623. case CM_EVENT_BATT_FULL:
  1624. fullbatt_handler(cm);
  1625. break;
  1626. case CM_EVENT_BATT_OUT:
  1627. battout_handler(cm);
  1628. break;
  1629. case CM_EVENT_BATT_IN:
  1630. case CM_EVENT_EXT_PWR_IN_OUT ... CM_EVENT_CHG_START_STOP:
  1631. misc_event_handler(cm, type);
  1632. break;
  1633. case CM_EVENT_UNKNOWN:
  1634. case CM_EVENT_OTHERS:
  1635. uevent_notify(cm, msg ? msg : default_event_names[type]);
  1636. break;
  1637. default:
  1638. dev_err(cm->dev, "%s type not specified.\n", __func__);
  1639. break;
  1640. }
  1641. }
  1642. EXPORT_SYMBOL_GPL(cm_notify_event);
  1643. MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
  1644. MODULE_DESCRIPTION("Charger Manager");
  1645. MODULE_LICENSE("GPL");