mtk_charger.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2017. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. *
  31. * The following software/firmware and/or related documentation ("MediaTek Software")
  32. * have been modified by MediaTek Inc. All revisions are subject to any receiver\'s
  33. * applicable license agreements with MediaTek Inc.
  34. */
  35. #include <target/board.h>
  36. #include <kernel/thread.h>
  37. #include <platform/mt_typedefs.h>
  38. #include <platform/mt_reg_base.h>
  39. #include <platform/mt_pmic.h>
  40. #include <platform/upmu_hw.h>
  41. #include <platform/upmu_common.h>
  42. #include <platform/boot_mode.h>
  43. #include <platform/mt_gpt.h>
  44. #include <platform/mt_rtc.h>
  45. #include <platform/mt_rtc_hw.h>
  46. #include <platform/mt_pmic_wrap_init.h>
  47. #include <platform/mt_leds.h>
  48. #include <printf.h>
  49. #include <sys/types.h>
  50. #include <target/cust_battery.h>
  51. #include <libfdt.h>
  52. #include <lk_builtin_dtb.h>
  53. #include "mt_pumpexpress.h"
  54. #include "mtk_battery.h"
  55. #include "mtk_charger.h"
  56. #include "mtk_charger_intf.h"
  57. #include "tcpc_subpmic.h"
  58. #define MAX_SLEEP_LOOP 20
  59. #define VBUS_CHECK_COUNT 3
  60. static struct mtk_charger_info *primary_mchr;
  61. /*****************************************************************************
  62. * Global Variable
  63. ****************************************************************************/
  64. bool enable_mtk_charger = false;
  65. bool g_boot_reason_change = false;
  66. struct charger_custom_data chr_cust_data;
  67. /*****************************************************************************
  68. * Externl Variable
  69. ****************************************************************************/
  70. extern bool g_boot_menu;
  71. extern void mtk_wdt_restart(void);
  72. void mt65xx_bat_init(void){}
  73. void __attribute__((weak)) check_bat_status(void)
  74. {
  75. dprintf(CRITICAL, "%s: Please implement check_bat_status() if you don't use mtk charger.\n", __func__);
  76. }
  77. void __attribute__((weak)) enable_charging(bool enable)
  78. {
  79. dprintf(CRITICAL, "%s: Please implement enable_charging() if you don't use mtk charger.\n", __func__);
  80. }
  81. void __attribute__((weak)) enable_power_path(bool enable)
  82. {
  83. dprintf(CRITICAL, "%s: Please implement enable_power_path() if you don't use mtk charger.\n", __func__);
  84. }
  85. void __attribute__((weak)) enable_wdt(bool enable)
  86. {
  87. dprintf(CRITICAL, "%s: Please implement enable_wdt() if you don't use mtk charger.\n", __func__);
  88. }
  89. void __attribute__((weak)) charger_start(void)
  90. {
  91. dprintf(CRITICAL, "%s: Please implement charger_start() if you don't use mtk charger.\n", __func__);
  92. }
  93. int __attribute__((weak)) force_get_tbat(bool update)
  94. {
  95. dprintf(CRITICAL, "%s: T is not ready.\n", __func__);
  96. return 25;
  97. }
  98. int __attribute__((weak)) gauge_get_current(bool *curr_sign, int *bat_current)
  99. {
  100. dprintf(CRITICAL, "%s: IBAT is not ready.\n", __func__);
  101. *curr_sign = 1;
  102. *bat_current = 5000;
  103. return 0;
  104. }
  105. void __attribute__((weak)) mt_disp_show_charging(int index)
  106. {
  107. dprintf(CRITICAL, "%s: logo is not ready.\n", __func__);
  108. }
  109. void __attribute__((weak)) mt_disp_show_plug_charger(void)
  110. {
  111. dprintf(CRITICAL, "%s: logo is not ready.\n", __func__);
  112. }
  113. void __attribute__((weak)) mt_disp_show_charger_ov_logo(void)
  114. {
  115. dprintf(CRITICAL, "%s: logo is not ready.\n", __func__);
  116. }
  117. unsigned int chr_fdt_getprop_bool(const void *fdt, int nodeoffset,
  118. const char *name)
  119. {
  120. const void *data = NULL;
  121. int len = 0;
  122. data = fdt_getprop(fdt, nodeoffset, name, &len);
  123. if (data)
  124. return true;
  125. else
  126. return false;
  127. }
  128. void chr_fdt_getprop_char_array(const void *fdt, int nodeoffset,
  129. const char *name, char *out_value)
  130. {
  131. const void *data = NULL;
  132. int len = 0;
  133. data = fdt_getprop(fdt, nodeoffset, name, &len);
  134. if (len > 0 && data)
  135. memcpy(out_value, data, len);
  136. else
  137. memset(out_value, 0, len);
  138. }
  139. unsigned int chr_fdt_getprop_u32(const void *fdt, int nodeoffset,
  140. const char *name)
  141. {
  142. const void *data = NULL;
  143. int len = 0;
  144. data = fdt_getprop(fdt, nodeoffset, name, &len);
  145. if (len > 0 && data)
  146. return fdt32_to_cpu(*(unsigned int *)data);
  147. else
  148. return 0;
  149. }
  150. void init_charger_custom_data(void)
  151. {
  152. chr_cust_data.disable_charger = false;
  153. chr_cust_data.power_path_support = true;
  154. chr_cust_data.enable_pe_plus = true;
  155. chr_cust_data.max_charger_voltage = 6500;
  156. chr_cust_data.min_charger_voltage = 4000;
  157. chr_cust_data.fast_charge_voltage = 3000;
  158. /* charging current */
  159. chr_cust_data.usb_charger_current = 500;
  160. chr_cust_data.ac_charger_current = 2050;
  161. chr_cust_data.ac_charger_input_current = 3200;
  162. chr_cust_data.non_std_ac_charger_current = 500;
  163. chr_cust_data.charging_host_charger_current = 500;
  164. chr_cust_data.ta_ac_charger_current = 3000;
  165. chr_cust_data.pd_charger_current = 500;
  166. /* temperature protection ref sw jeita */
  167. chr_cust_data.temp_t4_threshold = 50;
  168. chr_cust_data.temp_t3_threshold = 45;
  169. chr_cust_data.temp_t1_threshold = 0;
  170. /* charging anime */
  171. chr_cust_data.enable_anime = false;
  172. chr_cust_data.led_brightness = 20;
  173. chr_cust_data.blinking_times = 6;
  174. chr_cust_data.blinking_period = 1500;
  175. /* vbus resistance */
  176. chr_cust_data.r_charger_1 = 330;
  177. chr_cust_data.r_charger_2 = 39;
  178. }
  179. int init_cust_data_from_dt(void)
  180. {
  181. int offset, val;
  182. offset = fdt_node_offset_by_compatible(get_lk_overlayed_dtb(), -1, "mediatek,lk_charger");
  183. if (offset >= 0) {
  184. val = chr_fdt_getprop_bool(get_lk_overlayed_dtb(), offset, "disable_charger");
  185. if (val)
  186. chr_cust_data.disable_charger = true;
  187. else
  188. chr_cust_data.disable_charger = false;
  189. val = chr_fdt_getprop_bool(get_lk_overlayed_dtb(), offset, "enable_pe_plus");
  190. if (val)
  191. chr_cust_data.enable_pe_plus = true;
  192. else
  193. chr_cust_data.enable_pe_plus = false;
  194. val = chr_fdt_getprop_bool(get_lk_overlayed_dtb(), offset, "enable_pd20_reset");
  195. if (val)
  196. chr_cust_data.enable_pd20_reset = true;
  197. else
  198. chr_cust_data.enable_pd20_reset = false;
  199. val = chr_fdt_getprop_bool(get_lk_overlayed_dtb(), offset, "power_path_support");
  200. if (val)
  201. chr_cust_data.power_path_support = true;
  202. else
  203. chr_cust_data.power_path_support = false;
  204. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "max_charger_voltage");
  205. if (val)
  206. chr_cust_data.max_charger_voltage = val / 1000;
  207. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "min_charger_voltage");
  208. if (val)
  209. chr_cust_data.min_charger_voltage = val / 1000;
  210. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "fast_charge_voltage");
  211. if (val)
  212. chr_cust_data.fast_charge_voltage = val / 1000;
  213. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "usb_charger_current");
  214. if (val)
  215. chr_cust_data.usb_charger_current = val / 1000;
  216. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "ac_charger_current");
  217. if (val)
  218. chr_cust_data.ac_charger_current = val / 1000;
  219. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "ac_charger_input_current");
  220. if (val)
  221. chr_cust_data.ac_charger_input_current = val / 1000;
  222. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "non_std_ac_charger_current");
  223. if (val)
  224. chr_cust_data.non_std_ac_charger_current = val / 1000;
  225. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "charging_host_charger_current");
  226. if (val)
  227. chr_cust_data.charging_host_charger_current = val / 1000;
  228. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "ta_ac_charger_current");
  229. if (val)
  230. chr_cust_data.ta_ac_charger_current = val / 1000;
  231. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "pd_charger_current");
  232. if (val)
  233. chr_cust_data.pd_charger_current = val / 1000;
  234. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "temp_t4_threshold");
  235. if (val)
  236. chr_cust_data.temp_t4_threshold = val;
  237. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "temp_t3_threshold");
  238. if (val)
  239. chr_cust_data.temp_t3_threshold = val;
  240. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "temp_t1_threshold");
  241. if (val)
  242. chr_cust_data.temp_t1_threshold = val;
  243. val = chr_fdt_getprop_bool(get_lk_overlayed_dtb(), offset, "enable_anime");
  244. if (val)
  245. chr_cust_data.enable_anime = true;
  246. else
  247. chr_cust_data.enable_anime = false;
  248. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "led_brightness");
  249. if (val)
  250. chr_cust_data.led_brightness = val;
  251. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "blinking_times");
  252. if (val)
  253. chr_cust_data.blinking_times = val;
  254. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "blinking_period");
  255. if (val)
  256. chr_cust_data.blinking_period = val;
  257. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "r_charger_1");
  258. if (val)
  259. chr_cust_data.r_charger_1 = val;
  260. val = chr_fdt_getprop_u32(get_lk_overlayed_dtb(), offset, "r_charger_2");
  261. if (val)
  262. chr_cust_data.r_charger_2 = val;
  263. dprintf(CRITICAL, "[%s]:chroff:%d,pe:%d,powpath:%d,vchrmax:%d,vchrmin:%d,vfast:%d,"
  264. "usb:%d,ac:%d %d,nac:%d,cdp:%d,ta:%d,pd:%d,t:%d %d %d\n", __func__,
  265. chr_cust_data.disable_charger, chr_cust_data.enable_pe_plus,
  266. chr_cust_data.power_path_support, chr_cust_data.max_charger_voltage,
  267. chr_cust_data.min_charger_voltage, chr_cust_data.fast_charge_voltage,
  268. chr_cust_data.usb_charger_current, chr_cust_data.ac_charger_current,
  269. chr_cust_data.ac_charger_input_current, chr_cust_data.non_std_ac_charger_current,
  270. chr_cust_data.charging_host_charger_current, chr_cust_data.ta_ac_charger_current,
  271. chr_cust_data.pd_charger_current, chr_cust_data.temp_t4_threshold,
  272. chr_cust_data.temp_t3_threshold, chr_cust_data.temp_t1_threshold);
  273. enable_mtk_charger = true;
  274. return 0;
  275. }
  276. else {
  277. dprintf(CRITICAL, "[%s]: lk_charger is not found in dts!\n", __func__);
  278. enable_mtk_charger = false;
  279. return 1;
  280. }
  281. }
  282. void chr_power_off(void)
  283. {
  284. #ifdef MTK_PMIC_POWER_OFF
  285. mt_power_off();
  286. #else
  287. mt6575_power_off();
  288. #endif
  289. }
  290. int get_chr_volt(void)
  291. {
  292. unsigned int val = 0;
  293. #ifdef PMU_CHARGER_GET_VBUS
  294. mtk_charger_get_vbus(primary_mchr, &val);
  295. val /= 1000;
  296. dprintf(CRITICAL, "%s: vbus = %d mV\n", __func__, val);
  297. #else
  298. val = pmic_get_auxadc_value(AUXADC_LIST_VCDT);
  299. val = (((chr_cust_data.r_charger_1 + chr_cust_data.r_charger_2) * 100 * val)
  300. / chr_cust_data.r_charger_2) / 100;
  301. #endif
  302. return val;
  303. }
  304. int get_bat_volt(int times)
  305. {
  306. int bat_vol;
  307. if (chr_cust_data.power_path_support == true)
  308. bat_vol = get_i_sense_volt(times);
  309. else
  310. bat_vol = get_bat_sense_volt(times);
  311. return bat_vol;
  312. }
  313. bool is_power_path_supported(void)
  314. {
  315. return chr_cust_data.power_path_support;
  316. }
  317. bool is_disable_charger(void)
  318. {
  319. return chr_cust_data.disable_charger;
  320. }
  321. bool is_battery_on(void)
  322. {
  323. /* FIXME: Need to replace with general PMIC interface */
  324. pmic_set_register_value(PMIC_RG_BATON_EN, 1);
  325. #if defined(MACH_TYPE_MT6765) || defined(MACH_TYPE_MT6761) || defined(MACH_TYPE_MT8168)
  326. if (pmic_get_register_value(PMIC_RGS_BATON_UNDET) == 1)
  327. #else
  328. if (pmic_get_register_value(PMIC_AD_BATON_UNDET) == 1)
  329. #endif
  330. return false;
  331. else
  332. return true;
  333. }
  334. bool is_low_battery(int val)
  335. {
  336. static unsigned char g_bat_low = 0xFF;
  337. //low battery only just once in lk
  338. if (0 == val) {
  339. if (0xFF != g_bat_low)
  340. return g_bat_low;
  341. else
  342. g_bat_low = false;
  343. val = get_bat_volt(1);
  344. }
  345. if (val < BATTERY_LOWVOL_THRESOLD) {
  346. dprintf(INFO, "%s, TRUE\n", __func__);
  347. g_bat_low = true;
  348. }
  349. else {
  350. dprintf(INFO, "%s, FALSE\n", __func__);
  351. g_bat_low = false;
  352. }
  353. return g_bat_low;
  354. }
  355. static void select_charging_current_limit(void)
  356. {
  357. int input_current_limit;
  358. int charging_current_limit;
  359. CHARGER_TYPE chr_type = g_boot_arg->charger_type;
  360. dprintf(INFO, "charger_type: %d\n", chr_type);
  361. if (chr_type == STANDARD_HOST) {
  362. input_current_limit = chr_cust_data.usb_charger_current;
  363. charging_current_limit = chr_cust_data.usb_charger_current;
  364. } else if (chr_type == NONSTANDARD_CHARGER) {
  365. input_current_limit = chr_cust_data.non_std_ac_charger_current;
  366. charging_current_limit = chr_cust_data.non_std_ac_charger_current;
  367. } else if (chr_type == STANDARD_CHARGER) {
  368. input_current_limit = chr_cust_data.ac_charger_input_current;
  369. charging_current_limit = chr_cust_data.ac_charger_current;
  370. } else if (chr_type == CHARGING_HOST) {
  371. input_current_limit = chr_cust_data.charging_host_charger_current;
  372. charging_current_limit = chr_cust_data.charging_host_charger_current;
  373. } else {
  374. input_current_limit = chr_cust_data.usb_charger_current;
  375. charging_current_limit = chr_cust_data.usb_charger_current;
  376. }
  377. mtk_charger_set_aicr(primary_mchr, input_current_limit);
  378. mtk_charger_set_ichg(primary_mchr, charging_current_limit);
  379. }
  380. static void reset_default_charging_current_limit(void)
  381. {
  382. int input_current_limit;
  383. int charging_current_limit;
  384. input_current_limit = chr_cust_data.usb_charger_current;
  385. charging_current_limit = chr_cust_data.usb_charger_current;
  386. mtk_charger_set_aicr(primary_mchr, input_current_limit);
  387. mtk_charger_set_ichg(primary_mchr, charging_current_limit);
  388. }
  389. static void show_plug_out_notify(void)
  390. {
  391. mt_disp_show_charger_ov_logo();
  392. mt65xx_backlight_on();
  393. thread_sleep(4000);
  394. mt65xx_backlight_off();
  395. }
  396. static void show_low_battery_notify(void)
  397. {
  398. mt_disp_show_plug_charger();
  399. mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, chr_cust_data.led_brightness);
  400. thread_sleep(4000);
  401. mt65xx_backlight_off();
  402. }
  403. static void check_charger_battery_on(void)
  404. {
  405. if (upmu_is_chr_det() == false) {
  406. dprintf(CRITICAL, "[BATTERY] No Charger, Power OFF !\n");
  407. show_low_battery_notify();
  408. chr_power_off();
  409. }
  410. if (!is_battery_on()) {
  411. dprintf(CRITICAL, "[BATTERY] No battry plug-in. Power Off.");
  412. chr_power_off();
  413. }
  414. mtk_charger_check_charging_mode(primary_mchr);
  415. }
  416. static void show_charging_anime(void)
  417. {
  418. int i, j;
  419. bool stop = false;
  420. mt_disp_show_charging(0);
  421. /* set LCD brightness */
  422. mt65xx_leds_brightness_set(MT65XX_LED_TYPE_LCD, chr_cust_data.led_brightness);
  423. /* set blinking times */
  424. for (i = 0; i < chr_cust_data.blinking_times && !stop; i++) {
  425. mtk_wdt_restart();
  426. mt_disp_show_charging(i % 2);
  427. for (j = 0; j < 2 && !stop; j++) {
  428. /* set blinking period */
  429. thread_sleep(chr_cust_data.blinking_period);
  430. check_charger_battery_on();
  431. if(get_powerkey_pressed_status()) {
  432. clear_powerkey_pressed_status();
  433. stop = true;
  434. }
  435. }
  436. }
  437. mt65xx_backlight_off();
  438. mtk_charger_reset_wdt(primary_mchr);
  439. }
  440. void check_charger_volt(void)
  441. {
  442. int i, j;
  443. int chr_volt;
  444. if (!primary_mchr)
  445. primary_mchr = mtk_charger_get_by_name("primary_charger");
  446. if (!primary_mchr) {
  447. dprintf(CRITICAL, "%s: get primary charger failed\n", __func__);
  448. return;
  449. }
  450. if (g_boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT ||
  451. g_boot_mode == LOW_POWER_OFF_CHARGING_BOOT) {
  452. for (i = 0; i < VBUS_CHECK_COUNT; i++) {
  453. chr_volt = get_chr_volt();
  454. if (chr_volt < chr_cust_data.min_charger_voltage) {
  455. dprintf(INFO, "vbus is less than %dmv, power off\n",
  456. chr_cust_data.min_charger_voltage);
  457. if (!upmu_is_chr_det())
  458. goto power_off;
  459. pd_inc_cc_det_lower_bound();
  460. /* maximum time of VBUS discharge: 1s */
  461. mtk_charger_enable_discharge(primary_mchr, true);
  462. for (j = 0; upmu_is_chr_det() && j < 100; j++)
  463. mdelay(10);
  464. mtk_charger_enable_discharge(primary_mchr, false);
  465. mtk_charger_sw_reset(primary_mchr);
  466. power_off:
  467. chr_power_off();
  468. }
  469. }
  470. }
  471. if (chr_cust_data.power_path_support == true) {
  472. chr_volt = get_chr_volt();
  473. if (chr_volt > chr_cust_data.max_charger_voltage) {
  474. dprintf(CRITICAL, "Charger Over Voltage:%d\n, power off...", chr_volt);
  475. show_plug_out_notify();
  476. chr_power_off();
  477. }
  478. }
  479. }
  480. /*
  481. * enter this function when low battery with charger
  482. */
  483. void check_bat_protect_status(void)
  484. {
  485. int ret = 0;
  486. int bat_val = 0;
  487. int i;
  488. int temperature;
  489. int bat_current = 0;
  490. bool curr_sign = 0;
  491. static bool is_first = 1;
  492. if (enable_mtk_charger == false) {
  493. check_bat_status();
  494. return;
  495. }
  496. ret = mtk_charger_enable_charging(primary_mchr, false);
  497. if (ret < 0)
  498. dprintf(CRITICAL, "%s: disable charging failed, ret = %d\n", __func__, ret);
  499. bat_val = get_bat_volt(5);
  500. dprintf(CRITICAL, "[%s]: check VBAT=%d mV with %d mV\n", __func__,
  501. bat_val, BATTERY_LOWVOL_THRESOLD);
  502. clear_powerkey_pressed_status();
  503. unsigned int time_charging;
  504. time_charging = get_timer(0);
  505. //unsigned int time_sleeping;
  506. while (bat_val < BATTERY_LOWVOL_THRESOLD) {
  507. mtk_wdt_restart();
  508. mtk_charger_reset_wdt(primary_mchr);
  509. check_charger_battery_on();
  510. check_charger_volt();
  511. temperature = force_get_tbat(true);
  512. dprintf(INFO, "%s: T=%d\n", __func__, temperature);
  513. if(temperature > chr_cust_data.temp_t4_threshold) {
  514. dprintf(CRITICAL,"[BATTERY] Battery over Temperature or NTC fail %d %d!!\n\r", temperature,
  515. chr_cust_data.temp_t4_threshold);
  516. break;
  517. }
  518. if (bat_val < chr_cust_data.fast_charge_voltage ||
  519. temperature > chr_cust_data.temp_t3_threshold ||
  520. temperature < chr_cust_data.temp_t1_threshold)
  521. reset_default_charging_current_limit();
  522. else
  523. select_charging_current_limit();
  524. ret = mtk_charger_enable_charging(primary_mchr, true);
  525. if (ret < 0)
  526. dprintf(CRITICAL, "%s: enable charging failed, ret = %d\n", __func__, ret);
  527. //time_sleeping = get_timer(0);
  528. if (chr_cust_data.enable_anime && bat_val > chr_cust_data.fast_charge_voltage) {
  529. if (is_first) {
  530. show_charging_anime();
  531. is_first = 0;
  532. }
  533. for (i = 0; i < MAX_SLEEP_LOOP; i++) {
  534. mtk_wdt_restart();
  535. check_charger_battery_on();
  536. /* set polling period */
  537. thread_sleep(1000);
  538. if(get_powerkey_pressed_status()) {
  539. clear_powerkey_pressed_status();
  540. show_charging_anime();
  541. }
  542. }
  543. } else {
  544. for (i = 0; i < MAX_SLEEP_LOOP; i++) {
  545. mtk_wdt_restart();
  546. check_charger_battery_on();
  547. /* set polling period */
  548. thread_sleep(1000);
  549. }
  550. }
  551. //dprintf(CRITICAL, "[PROFILE] ------- charging %d ms -------- \n", (int)get_timer(time_sleeping));
  552. if (is_battery_on()) {
  553. gauge_get_current(&curr_sign, &bat_current);
  554. bat_current = bat_current / 10;
  555. dprintf(INFO, "%s:IBAT=%d\n", __func__, curr_sign ? bat_current : -1 * bat_current);
  556. }
  557. if (g_boot_arg->charger_type == STANDARD_CHARGER && bat_val > chr_cust_data.fast_charge_voltage) {
  558. ret = mtk_charger_enable_charging(primary_mchr, false);
  559. if (ret < 0)
  560. dprintf(INFO, "%s: disable charging failed, ret = %d\n", __func__, ret);
  561. }
  562. bat_val = get_bat_volt(5);
  563. dprintf(INFO, "[%s]: check VBAT=%d mV with %d mV, start charging...\n", __func__,
  564. bat_val, BATTERY_LOWVOL_THRESOLD);
  565. }
  566. dprintf(INFO, "[PROFILE] ------- Charging takes %d ms -------- \n", (int)get_timer(time_charging));
  567. mtk_wdt_restart();
  568. reset_default_charging_current_limit();
  569. }
  570. void check_low_battery(void)
  571. {
  572. int bat_vol;
  573. bat_vol = get_bat_volt(1);
  574. if (is_low_battery(bat_vol)) {
  575. if (g_boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT && upmu_is_chr_det() == true) {
  576. dprintf(CRITICAL, "[%s] Kernel Low Battery Power Off Charging Mode\n", __func__);
  577. g_boot_mode = LOW_POWER_OFF_CHARGING_BOOT;
  578. check_bat_protect_status();
  579. } else {
  580. dprintf(CRITICAL, "[BATTERY] battery voltage(%dmV) <= CLV ! Can not Boot Linux Kernel !! \n\r",bat_vol);
  581. show_low_battery_notify();
  582. chr_power_off();
  583. }
  584. }
  585. }
  586. void reset_pd_adapter(void)
  587. {
  588. int chr_volt;
  589. if (!primary_mchr)
  590. primary_mchr = mtk_charger_get_by_name("primary_charger");
  591. if (!primary_mchr) {
  592. dprintf(CRITICAL, "%s: get primary charger failed\n", __func__);
  593. return;
  594. }
  595. if (!chr_cust_data.enable_pd20_reset)
  596. return;
  597. chr_volt = get_chr_volt();
  598. /* Try reset pd charger TA */
  599. if (chr_volt > chr_cust_data.max_charger_voltage) {
  600. dprintf(CRITICAL,
  601. "[mt65xx_bat_init] Try reset pd20 charger TA\n");
  602. pd_reset_adapter();
  603. }
  604. }
  605. void reset_pe_adapter(void)
  606. {
  607. if (!primary_mchr)
  608. primary_mchr = mtk_charger_get_by_name("primary_charger");
  609. if (!primary_mchr) {
  610. dprintf(CRITICAL, "%s: get primary charger failed\n", __func__);
  611. return;
  612. }
  613. if (chr_cust_data.enable_pe_plus == true) {
  614. int chr_volt;
  615. int rc = 0;
  616. /*Try to reset PE+ adapter once abnormal voltage is found*/
  617. chr_volt = get_chr_volt();
  618. while (chr_volt > chr_cust_data.max_charger_voltage) {
  619. dprintf(CRITICAL, "[mt65xx_bat_init] PE+ adpater should be reset to 5V now\n");
  620. pumpex_reset_adapter_enable(1);
  621. mdelay(250);
  622. pumpex_reset_adapter_enable(0);
  623. chr_volt = get_chr_volt();
  624. rc++;
  625. if (rc == 3)
  626. break;
  627. }
  628. }
  629. }
  630. void charger_enable_charging(bool enable)
  631. {
  632. int ret = 0;
  633. if (enable_mtk_charger == false) {
  634. enable_charging(enable);
  635. return;
  636. }
  637. primary_mchr = mtk_charger_get_by_name("primary_charger");
  638. if (!primary_mchr) {
  639. dprintf(CRITICAL, "%s: get primary charger failed\n", __func__);
  640. return;
  641. }
  642. ret = mtk_charger_enable_charging(primary_mchr, enable);
  643. if (ret < 0)
  644. dprintf(CRITICAL, "%s: enable/disable charging failed, ret = %d\n", __func__, ret);
  645. else {
  646. if(enable)
  647. dprintf(INFO, "%s: enable charging\n", __func__);
  648. else
  649. dprintf(INFO, "%s: disable charging\n", __func__);
  650. }
  651. }
  652. void charger_enable_power_path(bool enable)
  653. {
  654. int ret = 0;
  655. if (enable_mtk_charger == false) {
  656. enable_power_path(enable);
  657. return;
  658. }
  659. if (is_battery_on()) {
  660. primary_mchr = mtk_charger_get_by_name("primary_charger");
  661. if (!primary_mchr) {
  662. dprintf(CRITICAL, "%s: get primary charger failed\n", __func__);
  663. return;
  664. }
  665. ret = mtk_charger_enable_power_path(primary_mchr, enable);
  666. if (ret < 0)
  667. dprintf(CRITICAL, "%s: enable/disable power path failed, ret = %d\n", __func__, ret);
  668. }
  669. else
  670. dprintf(CRITICAL, "%s: no battery plug-in, skip power path control\n", __func__);
  671. }
  672. void charger_enable_wdt(bool enable)
  673. {
  674. int ret = 0;
  675. if (enable_mtk_charger == false) {
  676. enable_wdt(enable);
  677. return;
  678. }
  679. primary_mchr = mtk_charger_get_by_name("primary_charger");
  680. if (!primary_mchr) {
  681. dprintf(CRITICAL, "%s: get primary charger failed\n", __func__);
  682. return;
  683. }
  684. ret = mtk_charger_enable_wdt(primary_mchr, enable);
  685. if (ret < 0)
  686. dprintf(CRITICAL, "%s: enable/disable wdt failed, ret = %d\n", __func__, ret);
  687. else {
  688. if(enable)
  689. dprintf(INFO, "%s: enable wdt\n", __func__);
  690. else
  691. dprintf(INFO, "%s: disable wdt\n", __func__);
  692. }
  693. }
  694. void mtk_charger_start(void)
  695. {
  696. if (enable_mtk_charger == false) {
  697. charger_start();
  698. return;
  699. }
  700. if (chr_cust_data.disable_charger == false) {
  701. int ret = 0;
  702. /* Get charger interface */
  703. primary_mchr = mtk_charger_get_by_name("primary_charger");
  704. if (!primary_mchr) {
  705. dprintf(CRITICAL, "%s: get primary charger failed\n", __func__);
  706. return;
  707. }
  708. if (g_boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT && pmic_detect_powerkey()) {
  709. dprintf(CRITICAL, "[mt65xx_bat_init] KPOC+PWRKEY => change boot mode\n");
  710. g_boot_reason_change = true;
  711. }
  712. check_low_battery();
  713. if (g_boot_mode != META_BOOT && g_boot_mode != FACTORY_BOOT && g_boot_mode != ATE_FACTORY_BOOT) {
  714. if (!is_battery_on()) {
  715. dprintf(CRITICAL, "[BATTERY] No battry plug-in. Power Off.");
  716. chr_power_off();
  717. }
  718. }
  719. /* disable wdt in case entering fastboot later... */
  720. ret = mtk_charger_enable_wdt(primary_mchr, false);
  721. if (ret < 0)
  722. dprintf(CRITICAL, "%s: disable wdt fail\n", __func__);
  723. }
  724. else
  725. dprintf(CRITICAL, "%s: skip mtk_charger_start\n", __func__);
  726. }