mt6360_pmu_charger.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092
  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,
  9. * shall be strictly prohibited.
  10. */
  11. /* MediaTek Inc. (C) 2015. All rights reserved.
  12. *
  13. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  14. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  15. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  16. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  17. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  19. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  20. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  21. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  22. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY
  23. * ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY
  24. * THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL
  25. * ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO RECEIVER'S
  26. * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
  27. * RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
  28. * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  29. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  30. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  31. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  32. */
  33. #include <platform/mt_typedefs.h>
  34. #include <platform/errno.h>
  35. #include <platform/mt_i2c.h>
  36. #include <printf.h>
  37. #include <debug.h>
  38. #include <platform/timer.h>
  39. #include "mt6360_pmu_charger.h"
  40. #include "mtk_charger_intf.h"
  41. #define MT6360_PMU_CHARGER_LK_DRV_VERSION "1.0.0_MTK"
  42. /* ================= */
  43. /* Internal variable */
  44. /* ================= */
  45. enum mt6360_chg_mode {
  46. MT6360_CHG_MODE_UNKNOWN,
  47. MT6360_CHG_MODE_TRICHG,
  48. MT6360_CHG_MODE_PRECHG,
  49. MT6360_CHG_MODE_FASTCHG,
  50. };
  51. static const char *mt6360_chg_mode_name[] = {
  52. "unknown",
  53. "trickle-charge",
  54. "pre-charge",
  55. "fast-charge",
  56. };
  57. struct mt6360_pmu_chg_info {
  58. struct mtk_charger_info mchr_info;
  59. struct mt_i2c_t i2c;
  60. int i2c_log_level;
  61. u8 vid;
  62. u32 iprec;
  63. u32 ichg;
  64. u32 ichg_dis_chg;
  65. bool chg_en;
  66. u32 aicr;
  67. u32 mivr;
  68. u32 cv;
  69. bool wkard_en;
  70. };
  71. enum mt6360_iinlmtsel {
  72. MT6360_IIMLMTSEL_AICR_3250 = 0,
  73. MT6360_IIMLMTSEL_CHR_TYPE,
  74. MT6360_IINLMTSEL_AICR,
  75. MT6360_IINLMTSEL_LOWER_LEVEL, /* lower of above three */
  76. };
  77. enum mt6360_charging_status {
  78. MT6360_CHG_STATUS_READY = 0,
  79. MT6360_CHG_STATUS_PROGRESS,
  80. MT6360_CHG_STATUS_DONE,
  81. MT6360_CHG_STATUS_FAULT,
  82. MT6360_CHG_STATUS_MAX,
  83. };
  84. /* Charging status name */
  85. static const char *mt6360_chg_status_name[MT6360_CHG_STATUS_MAX] = {
  86. "ready", "progress", "done", "fault",
  87. };
  88. /* ========================= */
  89. /* I2C operations */
  90. /* ========================= */
  91. static int mt6360_i2c_write_byte(struct mt6360_pmu_chg_info *info,
  92. u8 cmd, u8 data)
  93. {
  94. struct mt_i2c_t *i2c = &info->i2c;
  95. int ret = I2C_OK;
  96. u8 write_buf[2] = {cmd, data};
  97. ret = i2c_write(i2c, write_buf, 2);
  98. if (ret != I2C_OK)
  99. dprintf(CRITICAL,
  100. "%s: I2CW[0x%02X] = 0x%02X failed, code = %d\n",
  101. __func__, cmd, data, ret);
  102. else
  103. dprintf(info->i2c_log_level, "%s: I2CW[0x%02X] = 0x%02X\n",
  104. __func__, cmd, data);
  105. return ret;
  106. }
  107. static int mt6360_i2c_read_byte(struct mt6360_pmu_chg_info *info,
  108. u8 cmd, u8 *data)
  109. {
  110. struct mt_i2c_t *i2c = &info->i2c;
  111. int ret = I2C_OK;
  112. u8 ret_data = cmd;
  113. ret = i2c_write_read(i2c, &ret_data, 1, 1);
  114. if (ret != I2C_OK)
  115. dprintf(CRITICAL, "%s: I2CR[0x%02X] failed, code = %d\n",
  116. __func__, cmd, ret);
  117. else {
  118. dprintf(info->i2c_log_level, "%s: I2CR[0x%02X] = 0x%02X\n",
  119. __func__, cmd, ret_data);
  120. *data = ret_data;
  121. }
  122. return ret;
  123. }
  124. static int mt6360_i2c_block_write(struct mt6360_pmu_chg_info *info,
  125. u8 cmd, int len, const u8 *data)
  126. {
  127. struct mt_i2c_t *i2c = &info->i2c;
  128. unsigned char write_buf[len + 1];
  129. write_buf[0] = cmd;
  130. memcpy(&write_buf[1], data, len);
  131. return i2c_write(i2c, write_buf, len + 1);
  132. }
  133. static int mt6360_i2c_block_read(struct mt6360_pmu_chg_info *info,
  134. u8 cmd, int len, u8 *data)
  135. {
  136. struct mt_i2c_t *i2c = &info->i2c;
  137. data[0] = cmd;
  138. return i2c_write_read(i2c, data, 1, len);
  139. }
  140. static int mt6360_i2c_update_bits(struct mt6360_pmu_chg_info *info,
  141. u8 cmd, u8 mask, u8 data)
  142. {
  143. int ret = 0;
  144. u8 reg_data = 0;
  145. ret = mt6360_i2c_read_byte(info, cmd, &reg_data);
  146. if (ret != I2C_OK)
  147. return ret;
  148. reg_data = reg_data & 0xFF;
  149. reg_data &= ~mask;
  150. reg_data |= (data & mask);
  151. return mt6360_i2c_write_byte(info, cmd, reg_data);
  152. }
  153. static inline int mt6360_set_bit(struct mt6360_pmu_chg_info *info,
  154. u8 reg, u8 mask)
  155. {
  156. return mt6360_i2c_update_bits(info, reg, mask, mask);
  157. }
  158. static inline int mt6360_clr_bit(struct mt6360_pmu_chg_info *info,
  159. u8 reg, u8 mask)
  160. {
  161. return mt6360_i2c_update_bits(info, reg, mask, 0x00);
  162. }
  163. /* ================== */
  164. /* internal functions */
  165. /* ================== */
  166. static int mt6360_enable_hidden_mode(struct mt6360_pmu_chg_info *info, bool en)
  167. {
  168. return mt6360_i2c_write_byte(info, MT6360_PMU_TM_PAS_CODE1, en ? 0x69 : 0);
  169. }
  170. static bool mt6360_is_hw_exist(struct mt6360_pmu_chg_info *info)
  171. {
  172. int ret = 0;
  173. u8 vid = 0, rev_id = 0;
  174. u8 data = 0;
  175. ret = mt6360_i2c_read_byte(info, MT6360_PMU_DEV_INFO, &data);
  176. if (ret != I2C_OK)
  177. return false;
  178. vid = data & 0xF0;
  179. rev_id = data & 0x0F;
  180. if (vid != MT6360_VENDOR_ID) {
  181. dprintf(CRITICAL, "%s: vid is not match(%d)\n", __func__, vid);
  182. return false;
  183. }
  184. dprintf(CRITICAL, "%s: rev_id = %d\n", __func__, rev_id);
  185. info->mchr_info.device_id = rev_id;
  186. info->vid = vid;
  187. return true;
  188. }
  189. static int mt6360_enable_ilim(struct mt6360_pmu_chg_info *info, bool enable)
  190. {
  191. dprintf(CRITICAL, "%s: enable ilim = %d\n", __func__, enable);
  192. return (enable ? mt6360_set_bit : mt6360_clr_bit)
  193. (info, MT6360_PMU_CHG_CTRL3, MT6360_MASK_ILIM_EN);
  194. }
  195. /* Select IINLMTSEL to use AICR */
  196. static int mt6360_select_input_current_limit(
  197. struct mt6360_pmu_chg_info *info, enum mt6360_iinlmtsel sel)
  198. {
  199. dprintf(CRITICAL, "%s: select input current limit = %d\n",
  200. __func__, sel);
  201. return mt6360_i2c_update_bits(info,
  202. MT6360_PMU_CHG_CTRL2,
  203. MT6360_MASK_IINLMTSEL,
  204. sel << MT6360_SHFT_IINLMTSEL);
  205. }
  206. static int mt6360_set_cv(struct mt6360_pmu_chg_info *info, u32 uV)
  207. {
  208. u8 data = 0;
  209. if (uV >= 3900)
  210. data = (uV - 3900) / 10;
  211. if (data > MT6360_VOREG_MAXVAL)
  212. data = MT6360_VOREG_MAXVAL;
  213. dprintf(CRITICAL, "%s: cv = %d\n", __func__, uV);
  214. return mt6360_i2c_update_bits(info,
  215. MT6360_PMU_CHG_CTRL4,
  216. MT6360_MASK_VOREG,
  217. data << MT6360_SHFT_VOREG);
  218. }
  219. static int mt6360_enable_wdt(struct mt6360_pmu_chg_info *info, bool en)
  220. {
  221. dprintf(CRITICAL, "%s: en = %d\n", __func__, en);
  222. return (en ? mt6360_set_bit : mt6360_clr_bit)
  223. (info, MT6360_PMU_CHG_CTRL13, MT6360_MASK_CHG_WDT_EN);
  224. }
  225. static int mt6360_get_charging_status(struct mt6360_pmu_chg_info *info,
  226. enum mt6360_charging_status *chg_stat)
  227. {
  228. int ret = 0;
  229. u8 data = 0;
  230. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_STAT, &data);
  231. if (ret != I2C_OK)
  232. return ret;
  233. *chg_stat = (data & MT6360_MASK_CHG_STAT) >> MT6360_SHFT_CHG_STAT;
  234. return ret;
  235. }
  236. static int mt6360_get_mivr(struct mt6360_pmu_chg_info *info, u32 *mivr)
  237. {
  238. int ret = 0;
  239. u8 data = 0;
  240. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_CTRL6, &data);
  241. if (ret != I2C_OK)
  242. return ret;
  243. data = (data & MT6360_MASK_MIVR) >> MT6360_SHFT_MIVR;
  244. *mivr = 3900 + (data * 100);
  245. return ret;
  246. }
  247. static int mt6360_get_ieoc(struct mt6360_pmu_chg_info *info, u32 *ieoc)
  248. {
  249. int ret = 0;
  250. u8 data = 0;
  251. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_CTRL9, &data);
  252. if (ret != I2C_OK)
  253. return ret;
  254. data = (data & MT6360_MASK_IEOC) >> MT6360_SHFT_IEOC;
  255. *ieoc = 100 + (data * 50);
  256. return ret;
  257. }
  258. static int mt6360_is_charging_enable(struct mt6360_pmu_chg_info *info,
  259. bool *enable)
  260. {
  261. int ret = 0;
  262. u8 data = 0;
  263. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_CTRL2, &data);
  264. if (ret != I2C_OK)
  265. return ret;
  266. *enable = (data & MT6360_MASK_CHG_EN) ? true : false;
  267. return ret;
  268. }
  269. /* =========================================================== */
  270. /* The following is implementation for interface of mt_charger */
  271. /* =========================================================== */
  272. static int mt_charger_set_ichg(struct mtk_charger_info *mchr_info, u32 ichg)
  273. {
  274. struct mt6360_pmu_chg_info *info =
  275. (struct mt6360_pmu_chg_info *)mchr_info;
  276. int ret = 0;
  277. u8 data = 0;
  278. dprintf(CRITICAL, "%s: ichg = %d\n", __func__, ichg);
  279. if (ichg >= 100)
  280. data = (ichg - 100) / 100;
  281. if (data > MT6360_ICHG_MAXVAL)
  282. data = MT6360_ICHG_MAXVAL;
  283. ret = mt6360_i2c_update_bits(info,
  284. MT6360_PMU_CHG_CTRL7,
  285. MT6360_MASK_ICHG,
  286. data << MT6360_SHFT_ICHG);
  287. if (ret < 0)
  288. dprintf(CRITICAL, "%s: fail(%d)\n", __func__, ret);
  289. else
  290. info->ichg = ichg;
  291. return ret;
  292. }
  293. static int mt_charger_enable_charging(struct mtk_charger_info *mchr_info,
  294. bool enable)
  295. {
  296. struct mt6360_pmu_chg_info *info =
  297. (struct mt6360_pmu_chg_info *)mchr_info;
  298. int ret = 0;
  299. u32 ichg_ramp_t = 0;
  300. u8 data = 0;
  301. if (info->chg_en == enable) {
  302. dprintf(CRITICAL,
  303. "%s: is the same, en = %d\n", __func__, enable);
  304. return 0;
  305. }
  306. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHRDET_STAT, &data);
  307. if (ret != I2C_OK)
  308. goto bypass_wkard;
  309. if (!(data & MT6360_MASK_CHRDET_EXT_EVT)) {
  310. dprintf(CRITICAL, "%s: pwr_rdy = 0, bypass wkard\n", __func__);
  311. goto bypass_wkard;
  312. }
  313. if (info->ichg < 500) {
  314. dprintf(CRITICAL, "%s: ichg < 500, bypass wkard\n", __func__);
  315. goto bypass_wkard;
  316. }
  317. /* Workaround for avoid vsys overshoot when charge disable */
  318. if (!enable) {
  319. info->ichg_dis_chg = info->ichg;
  320. ichg_ramp_t = (info->ichg - 500) / 50 * 2;
  321. /* Set ichg 500mA */
  322. ret = mt6360_i2c_update_bits(info,
  323. MT6360_PMU_CHG_CTRL7,
  324. MT6360_MASK_ICHG,
  325. 0x04 << MT6360_SHFT_ICHG);
  326. if (ret < 0) {
  327. dprintf(CRITICAL, "%s: set ichg fail\n", __func__);
  328. return ret;
  329. }
  330. mdelay(ichg_ramp_t);
  331. } else {
  332. if (info->ichg == info->ichg_dis_chg) {
  333. ret = mt_charger_set_ichg(mchr_info, info->ichg);
  334. if (ret < 0) {
  335. dprintf(CRITICAL,
  336. "%s: set ichg fail\n", __func__);
  337. return ret;
  338. }
  339. }
  340. }
  341. bypass_wkard:
  342. ret = (enable ? mt6360_set_bit : mt6360_clr_bit)
  343. (info, MT6360_PMU_CHG_CTRL2, MT6360_MASK_CHG_EN);
  344. if (ret < 0)
  345. dprintf(CRITICAL, "%s: fail, en = %d\n", __func__, enable);
  346. else
  347. info->chg_en = enable;
  348. return ret;
  349. }
  350. static int mt_charger_get_ichg(struct mtk_charger_info *mchr_info, u32 *ichg)
  351. {
  352. struct mt6360_pmu_chg_info *info =
  353. (struct mt6360_pmu_chg_info *)mchr_info;
  354. int ret = 0;
  355. u8 data = 0;
  356. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_CTRL7, &data);
  357. if (ret != I2C_OK)
  358. return ret;
  359. data = (data & MT6360_MASK_ICHG) >> MT6360_SHFT_ICHG;
  360. *ichg = 100 + (data * 100);
  361. return ret;
  362. }
  363. static int mt_charger_set_iprec(struct mtk_charger_info *mchr_info, u32 iprec)
  364. {
  365. struct mt6360_pmu_chg_info *info =
  366. (struct mt6360_pmu_chg_info *)mchr_info;
  367. u8 data = 0;
  368. dprintf(CRITICAL, "%s: iprec = %d\n", __func__, iprec);
  369. if (iprec >= 100)
  370. data = (iprec - 100) / 50;
  371. if (data > MT6360_IPREC_MAXVAL)
  372. data = MT6360_IPREC_MAXVAL;
  373. return mt6360_i2c_update_bits(info,
  374. MT6360_PMU_CHG_CTRL8,
  375. MT6360_MASK_IPREC,
  376. data << MT6360_SHFT_IPREC);
  377. }
  378. static enum mt6360_chg_mode mt6360_get_charging_mode(
  379. struct mt6360_pmu_chg_info *info)
  380. {
  381. int ret = 0;
  382. u8 data = 0;
  383. dprintf(CRITICAL, "%s\n", __func__);
  384. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_STAT, &data);
  385. if (ret < 0)
  386. return MT6360_CHG_MODE_UNKNOWN;
  387. if (data & MT6360_MASK_VBAT_TRI)
  388. return MT6360_CHG_MODE_TRICHG;
  389. return (data & MT6360_MASK_VBAT_LVL) ? MT6360_CHG_MODE_FASTCHG :
  390. MT6360_CHG_MODE_PRECHG;
  391. }
  392. static int mt_charger_set_ichg_ext(struct mtk_charger_info *mchr_info, u32 ichg)
  393. {
  394. struct mt6360_pmu_chg_info *info =
  395. (struct mt6360_pmu_chg_info *)mchr_info;
  396. enum mt6360_chg_mode cur_mode = MT6360_CHG_MODE_UNKNOWN;
  397. dprintf(CRITICAL, "%s: ichg = %u\n", __func__, ichg);
  398. cur_mode = mt6360_get_charging_mode(info);
  399. if (cur_mode == MT6360_CHG_MODE_UNKNOWN) {
  400. dprintf(CRITICAL, "%s: get charging mode fail\n", __func__);
  401. return -EINVAL;
  402. }
  403. info->ichg = ichg;
  404. if (cur_mode != MT6360_CHG_MODE_FASTCHG) {
  405. dprintf(CRITICAL, "%s: not in fast-charge mode\n", __func__);
  406. return 0;
  407. }
  408. if (info->wkard_en) {
  409. dprintf(CRITICAL, "%s: in work around\n", __func__);
  410. return 0;
  411. }
  412. return mt_charger_set_ichg(mchr_info, ichg);
  413. }
  414. static int mt_charger_get_aicr(struct mtk_charger_info *mchr_info, u32 *aicr)
  415. {
  416. struct mt6360_pmu_chg_info *info =
  417. (struct mt6360_pmu_chg_info *)mchr_info;
  418. int ret = 0;
  419. u8 data = 0;
  420. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_CTRL3, &data);
  421. if (ret != I2C_OK)
  422. return ret;
  423. data = (data & MT6360_MASK_AICR) >> MT6360_SHFT_AICR;
  424. *aicr = 100 + (data * 50);
  425. return ret;
  426. }
  427. static int mt6360_adc_get_process_val(struct mt6360_pmu_chg_info *info,
  428. enum mt6360_adc_channel chan, u32 *val)
  429. {
  430. int ret = 0;
  431. u8 data = 0;
  432. switch (chan) {
  433. case MT6360_ADC_USBID:
  434. case MT6360_ADC_VREF_TS:
  435. case MT6360_ADC_TS:
  436. *val *= 1250;
  437. break;
  438. case MT6360_ADC_TEMP_JC:
  439. *val -= 40;
  440. break;
  441. case MT6360_ADC_VBAT:
  442. case MT6360_ADC_VSYS:
  443. case MT6360_ADC_CHG_VDDP:
  444. *val *= 1250;
  445. break;
  446. case MT6360_ADC_VBUSDIV5:
  447. *val *= 6250;
  448. break;
  449. case MT6360_ADC_VBUSDIV2:
  450. case MT6360_ADC_IBAT:
  451. *val *= 2500;
  452. break;
  453. case MT6360_ADC_IBUS:
  454. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_CTRL3, &data);
  455. if (ret < 0)
  456. return ret;
  457. if (((data & 0xfc) >> 2) < 0x6)
  458. *val *= 1900;
  459. else
  460. *val *= 2500;
  461. break;
  462. default:
  463. break;
  464. }
  465. return ret;
  466. }
  467. static int mt_charger_get_adc(struct mtk_charger_info *mchr_info,
  468. int chan, u32 *val)
  469. {
  470. struct mt6360_pmu_chg_info *info =
  471. (struct mt6360_pmu_chg_info *)mchr_info;
  472. u8 tmp[3], rpt[3];
  473. u8 data = 0;
  474. int i, ret = 0, max_retry_cnt = 20;
  475. dprintf(CRITICAL, "%s: ++\n", __func__);
  476. if (chan >= MT6360_ADC_MAX) {
  477. dprintf(CRITICAL, "%s: undeine channel(%d)\n",
  478. __func__, chan);
  479. ret = -EINVAL;
  480. goto err_adc_init;
  481. }
  482. /* first reset all channels and adc en */
  483. memset(tmp, 0, sizeof(tmp));
  484. ret = mt6360_i2c_block_write(info, MT6360_PMU_ADC_CONFIG, 3, tmp);
  485. if (ret < 0) {
  486. dprintf(CRITICAL, "%s: reset all channels fail\n", __func__);
  487. goto err_adc_init;
  488. }
  489. /* enable adc_donei irq */
  490. ret = mt6360_clr_bit(info, MT6360_PMU_CHG_MASK6, MT6360_MASK_ADC_DONE);
  491. if (ret < 0) {
  492. dprintf(CRITICAL, "%s: unmask adc_donei fail\n", __func__);
  493. goto err_adc_conv;
  494. }
  495. /* select preferred channel : vbus */
  496. ret = mt6360_i2c_update_bits(info,
  497. MT6360_PMU_ADC_RPT_1, 0xf0, chan << 4);
  498. if (ret < 0) {
  499. dprintf(CRITICAL, "%s: select prefer channel fail\n", __func__);
  500. goto err_adc_conv;
  501. }
  502. /* enable vbus adc channel and adc_en */
  503. tmp[0] |= (1 << 7);
  504. if ((chan / 8) > 0)
  505. tmp[0] |= (1 << (chan % 8));
  506. else
  507. tmp[1] |= (1 << (chan % 8));
  508. ret = mt6360_i2c_block_write(info, MT6360_PMU_ADC_CONFIG, 2, tmp);
  509. if (ret < 0) {
  510. dprintf(CRITICAL,
  511. "%s: enable vbus adc and adc en fail\n", __func__);
  512. goto err_adc_conv;
  513. }
  514. /* wait adc conversion done */
  515. for (i = 0; i < max_retry_cnt; i++) {
  516. mdelay(30);
  517. /* read adc conversion donei event */
  518. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_IRQ6, &data);
  519. if (ret < 0)
  520. goto err_adc_conv;
  521. if (!(data & MT6360_MASK_ADC_DONE))
  522. continue;
  523. ret = mt6360_set_bit(info, MT6360_PMU_CHG_IRQ6,
  524. MT6360_MASK_ADC_DONE);
  525. if (ret < 0) {
  526. dprintf(CRITICAL,
  527. "%s: clear adc donei irq fail\n", __func__);
  528. goto err_adc_conv;
  529. }
  530. memset(rpt, 0, sizeof(rpt));
  531. ret = mt6360_i2c_block_read(info, MT6360_PMU_ADC_RPT_1, 3, rpt);
  532. if (ret < 0)
  533. goto err_adc_conv;
  534. if ((rpt[0] & 0x0f) != chan) {
  535. dprintf(CRITICAL, "%s: not want channel report(%d)\n",
  536. __func__, rpt[0]);
  537. continue;
  538. }
  539. *val = ((rpt[1] << 8) | rpt[2]);
  540. ret = mt6360_adc_get_process_val(info, chan, val);
  541. break;
  542. }
  543. if (i == max_retry_cnt) {
  544. dprintf(CRITICAL, "%s: reach adc retry cnt\n", __func__);
  545. ret = -EBUSY;
  546. goto err_adc_conv;
  547. }
  548. err_adc_conv:
  549. tmp[0] &= ~(0x7);
  550. tmp[1] = 0;
  551. mt6360_i2c_block_write(info, MT6360_PMU_ADC_CONFIG, 2, tmp);
  552. mt6360_set_bit(info, MT6360_PMU_CHG_MASK6, MT6360_MASK_ADC_DONE);
  553. err_adc_init:
  554. dprintf(CRITICAL, "%s: --\n", __func__);
  555. return ret;
  556. }
  557. static int mt_charger_get_vbus(struct mtk_charger_info *mchr_info, u32 *vbus)
  558. {
  559. return mt_charger_get_adc(mchr_info, MT6360_ADC_VBUSDIV5, vbus);
  560. }
  561. static int mt_charger_set_aicr(struct mtk_charger_info *mchr_info, u32 aicr)
  562. {
  563. struct mt6360_pmu_chg_info *info =
  564. (struct mt6360_pmu_chg_info *)mchr_info;
  565. u8 data = 0;
  566. dprintf(CRITICAL, "%s: aicr = %d\n", __func__, aicr);
  567. if (aicr >= 100)
  568. data = (aicr - 100) / 50;
  569. if (data > MT6360_AICR_MAXVAL)
  570. data = MT6360_AICR_MAXVAL;
  571. return mt6360_i2c_update_bits(info,
  572. MT6360_PMU_CHG_CTRL3,
  573. MT6360_MASK_AICR,
  574. data << MT6360_SHFT_AICR);
  575. }
  576. static int mt_charger_set_aicr_ext(struct mtk_charger_info *mchr_info, u32 aicr)
  577. {
  578. struct mt6360_pmu_chg_info *info =
  579. (struct mt6360_pmu_chg_info *)mchr_info;
  580. enum mt6360_chg_mode cur_mode = MT6360_CHG_MODE_UNKNOWN;
  581. dprintf(CRITICAL, "%s: aicr = %d\n", __func__, aicr);
  582. cur_mode = mt6360_get_charging_mode(info);
  583. if (cur_mode == MT6360_CHG_MODE_UNKNOWN) {
  584. dprintf(CRITICAL, "%s: get charging mode fail\n", __func__);
  585. return -EINVAL;
  586. }
  587. info->aicr = aicr;
  588. if (cur_mode != MT6360_CHG_MODE_FASTCHG) {
  589. dprintf(CRITICAL, "%s: not in fast-charge mode\n", __func__);
  590. return 0;
  591. }
  592. if (info->wkard_en) {
  593. dprintf(CRITICAL, "%s: in work around\n", __func__);
  594. return 0;
  595. }
  596. return mt_charger_set_aicr(mchr_info, aicr);
  597. }
  598. static int mt_charger_set_mivr(struct mtk_charger_info *mchr_info, u32 mivr)
  599. {
  600. struct mt6360_pmu_chg_info *info =
  601. (struct mt6360_pmu_chg_info *)mchr_info;
  602. u8 data = 0;
  603. dprintf(CRITICAL, "%s: mivr = %d\n", __func__, mivr);
  604. if (mivr >= 3900)
  605. data = (mivr - 3900) / 100;
  606. if (data > MT6360_MIVR_MAXVAL)
  607. data = MT6360_MIVR_MAXVAL;
  608. return mt6360_i2c_update_bits(info,
  609. MT6360_PMU_CHG_CTRL6,
  610. MT6360_MASK_MIVR,
  611. data << MT6360_SHFT_MIVR);
  612. }
  613. static int mt_charger_enable_power_path(struct mtk_charger_info *mchr_info,
  614. bool enable)
  615. {
  616. struct mt6360_pmu_chg_info *info =
  617. (struct mt6360_pmu_chg_info *)mchr_info;
  618. dprintf(CRITICAL, "%s: enable = %d\n", __func__, enable);
  619. return (enable ? mt6360_clr_bit : mt6360_set_bit)
  620. (info, MT6360_PMU_CHG_CTRL1, MT6360_MASK_FORCE_SLEEP);
  621. }
  622. static int mt_charger_reset_pumpx(struct mtk_charger_info *mchr_info,
  623. bool reset)
  624. {
  625. struct mt6360_pmu_chg_info *info =
  626. (struct mt6360_pmu_chg_info *)mchr_info;
  627. if (reset)
  628. mt_charger_get_aicr(mchr_info, &info->aicr);
  629. return mt_charger_set_aicr(mchr_info, reset ? 100 : info->aicr);
  630. }
  631. static int mt_charger_enable_wdt(struct mtk_charger_info *mchr_info, bool en)
  632. {
  633. struct mt6360_pmu_chg_info *info =
  634. (struct mt6360_pmu_chg_info *)mchr_info;
  635. return mt6360_enable_wdt(info, en);
  636. }
  637. static int mt_charger_dump_register(struct mtk_charger_info *mchr_info)
  638. {
  639. struct mt6360_pmu_chg_info *info =
  640. (struct mt6360_pmu_chg_info *)mchr_info;
  641. enum mt6360_charging_status chg_status = MT6360_CHG_STATUS_READY;
  642. u32 ichg = 0, aicr = 0, mivr = 0, ieoc = 0;
  643. bool chg_en = 0;
  644. int ret = 0;
  645. ret = mt_charger_get_ichg(mchr_info, &ichg);
  646. ret = mt_charger_get_aicr(mchr_info, &aicr);
  647. ret = mt6360_get_mivr(info, &mivr);
  648. ret = mt6360_get_ieoc(info, &ieoc);
  649. ret = mt6360_is_charging_enable(info, &chg_en);
  650. ret = mt6360_get_charging_status(info, &chg_status);
  651. dprintf(CRITICAL,
  652. "%s: ICHG = %dmA, AICR = %dmA, MIVR = %dmV, IEOC = %dmA\n",
  653. __func__, ichg, aicr, mivr, ieoc);
  654. dprintf(CRITICAL, "%s: CHG_EN = %d, CHG_STATUS = %s\n",
  655. __func__, chg_en, mt6360_chg_status_name[chg_status]);
  656. return ret;
  657. }
  658. static int mt6360_fix_current_accuracy(struct mtk_charger_info *mchr_info,
  659. bool enable)
  660. {
  661. struct mt6360_pmu_chg_info *info =
  662. (struct mt6360_pmu_chg_info *)mchr_info;
  663. u8 swit_feq[3] = { 0x80, 0x20, 0x00 };
  664. int i, ret = 0;
  665. if (!(info->wkard_en ^ enable))
  666. return 0;
  667. ret = mt6360_enable_hidden_mode(info, true);
  668. if (ret < 0) {
  669. dprintf(CRITICAL, "%s: enter hidden mode fail\n", __func__);
  670. return ret;
  671. }
  672. if (enable) {
  673. /* Set chg/otg switch frequence 0.75MHz */
  674. ret = mt6360_set_bit(info, MT6360_PMU_CHG_CTRL1, 0x80);
  675. if (ret < 0) {
  676. dprintf(CRITICAL,
  677. "%s: set switch feq to 0.75MHz fail\n",
  678. __func__);
  679. goto out;
  680. }
  681. /* Set buck slope ratio to 0.6x */
  682. ret = mt6360_i2c_update_bits(info, MT6360_PMU_CHG_HIDDEN_CTRL10,
  683. 0x07, 0);
  684. if (ret < 0) {
  685. dprintf(CRITICAL,
  686. "%s: set buck slope ratio 0.6x fail\n",
  687. __func__);
  688. goto out;
  689. }
  690. /* Set Power path MOS gate driving slew rate to 2x */
  691. ret = mt6360_set_bit(info, MT6360_PMU_CHG_HIDDEN_CTRL11, 0xC0);
  692. if (ret < 0) {
  693. dprintf(CRITICAL,
  694. "%s: set pp gate slew rate fail\n", __func__);
  695. goto out;
  696. }
  697. } else {
  698. /* Clear Power path MOS gate driving slew rate to 1x */
  699. ret = mt6360_clr_bit(info, MT6360_PMU_CHG_HIDDEN_CTRL11, 0xC0);
  700. if (ret < 0) {
  701. dprintf(CRITICAL,
  702. "%s: clr pp gate slew rate fail\n", __func__);
  703. goto out;
  704. }
  705. /* set buck slope ratio step 0.6x to 1.8x */
  706. for (i = 0; i < 7; i++) {
  707. ret = mt6360_i2c_update_bits(info,
  708. MT6360_PMU_CHG_HIDDEN_CTRL10, 0x07, i);
  709. if (ret < 0) {
  710. dprintf(CRITICAL,
  711. "%s: step up buck slope ratio fail\n",
  712. __func__);
  713. goto out;
  714. }
  715. }
  716. /* Set chg/otg switch frequence step 0.75->1.0->1.5MHz */
  717. for (i = 0; i < 3; i++) {
  718. ret = mt6360_i2c_update_bits(info, MT6360_PMU_CHG_CTRL1,
  719. 0xa0, swit_feq[i]);
  720. if (ret < 0) {
  721. dprintf(CRITICAL,
  722. "%s: step down switch feq fail\n",
  723. __func__);
  724. goto out;
  725. }
  726. }
  727. }
  728. info->wkard_en = enable;
  729. out:
  730. mt6360_enable_hidden_mode(info, false);
  731. return (ret < 0) ? ret : 0;
  732. }
  733. static int mt_charger_check_charging_mode(struct mtk_charger_info *mchr_info)
  734. {
  735. struct mt6360_pmu_chg_info *info =
  736. (struct mt6360_pmu_chg_info *)mchr_info;
  737. int ret = 0;
  738. static enum mt6360_chg_mode pre_mode = MT6360_CHG_MODE_UNKNOWN;
  739. enum mt6360_chg_mode cur_mode = MT6360_CHG_MODE_UNKNOWN;
  740. u8 data = 0;
  741. dprintf(CRITICAL, "%s\n", __func__);
  742. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHRDET_STAT, &data);
  743. if (ret < 0)
  744. return ret;
  745. if (!(data & MT6360_MASK_CHRDET_EXT_EVT)) {
  746. dprintf(CRITICAL, "%s: pwr_rdy = 0\n", __func__);
  747. return 0;
  748. }
  749. ret = mt6360_i2c_read_byte(info, MT6360_PMU_CHG_CTRL2, &data);
  750. if (ret < 0)
  751. return ret;
  752. if (!(data & MT6360_MASK_CFO_EN)) {
  753. dprintf(CRITICAL, "%s: CFO_EN = 0\n", __func__);
  754. return 0;
  755. }
  756. cur_mode = mt6360_get_charging_mode(info);
  757. if (cur_mode == MT6360_CHG_MODE_UNKNOWN) {
  758. dprintf(CRITICAL, "%s: get charging mode fail\n", __func__);
  759. return -EINVAL;
  760. }
  761. dprintf(CRITICAL, "%s: in %s mode, previously in %s mode\n", __func__,
  762. mt6360_chg_mode_name[cur_mode],
  763. mt6360_chg_mode_name[pre_mode]);
  764. if (cur_mode == pre_mode)
  765. return 0;
  766. switch (cur_mode) {
  767. case MT6360_CHG_MODE_TRICHG:
  768. ret = mt_charger_set_ichg(mchr_info, info->iprec);
  769. if (ret < 0) {
  770. dprintf(CRITICAL,
  771. "%s: set ichg to %umA fail\n",
  772. __func__, info->iprec);
  773. return ret;
  774. }
  775. ret = mt6360_fix_current_accuracy(mchr_info, true);
  776. if (ret < 0) {
  777. dprintf(CRITICAL,
  778. "%s: fix current accuracy fail\n", __func__);
  779. return ret;
  780. }
  781. break;
  782. case MT6360_CHG_MODE_PRECHG:
  783. ret = mt_charger_set_ichg(mchr_info, info->iprec);
  784. if (ret < 0) {
  785. dprintf(CRITICAL,
  786. "%s: set ichg to %umA fail\n",
  787. __func__, info->iprec);
  788. return ret;
  789. }
  790. ret = mt6360_fix_current_accuracy(mchr_info,
  791. (info->iprec < 500) ?
  792. true : false);
  793. if (ret < 0) {
  794. dprintf(CRITICAL,
  795. "%s: fix current accuracy fail\n", __func__);
  796. return ret;
  797. }
  798. break;
  799. case MT6360_CHG_MODE_FASTCHG:
  800. ret = mt6360_fix_current_accuracy(mchr_info, false);
  801. if (ret < 0) {
  802. dprintf(CRITICAL,
  803. "%s: fix current accuracy fail\n", __func__);
  804. return ret;
  805. }
  806. ret = mt_charger_set_aicr(mchr_info, info->aicr);
  807. if (ret < 0) {
  808. dprintf(CRITICAL,
  809. "%s: set aicr to %umA fail\n",
  810. __func__, info->aicr);
  811. return ret;
  812. }
  813. ret = mt_charger_set_ichg(mchr_info, info->ichg);
  814. if (ret < 0) {
  815. dprintf(CRITICAL,
  816. "%s: set ichg to %umA fail\n",
  817. __func__, info->ichg);
  818. return ret;
  819. }
  820. break;
  821. default:
  822. dprintf(CRITICAL, "%s: Unkown mode\n", __func__);
  823. break;
  824. }
  825. pre_mode = cur_mode;
  826. return 0;
  827. }
  828. static int mt_charger_enable_discharge(struct mtk_charger_info *mchr_info, bool en)
  829. {
  830. struct mt6360_pmu_chg_info *info =
  831. (struct mt6360_pmu_chg_info *)mchr_info;
  832. int ret = 0;
  833. dprintf(CRITICAL, "%s: en = %d\n", __func__, en);
  834. ret = mt6360_enable_hidden_mode(info, true);
  835. if (ret < 0)
  836. return ret;
  837. /* Set bit2 of reg[0x31] to 1/0 to enable/disable discharging */
  838. ret = mt6360_i2c_update_bits(info, MT6360_PMU_CHG_HIDDEN_CTRL2,
  839. MT6360_MASK_DISCHG, en ? 0xff : 0);
  840. if (ret < 0)
  841. dprintf(CRITICAL, "%s: fail(%d)\n", __func__, ret);
  842. mt6360_enable_hidden_mode(info, false);
  843. return ret;
  844. }
  845. static int mt_charger_sw_reset(struct mtk_charger_info *mchr_info)
  846. {
  847. struct mt6360_pmu_chg_info *info =
  848. (struct mt6360_pmu_chg_info *)mchr_info;
  849. int ret = 0;
  850. u32 i = 0;
  851. u8 cmds[3] = {MT6360_PMU_RST_PAS_CODE1, MT6360_PMU_RST_PAS_CODE2,
  852. MT6360_PMU_RST1};
  853. u8 data[3] = {0xA9, 0x96, 0x7F};
  854. for (i = 0; i < ARRAY_SIZE(cmds); i++) {
  855. ret = mt6360_i2c_write_byte(info, cmds[i], data[i]);
  856. if (ret < 0) {
  857. dprintf(CRITICAL, "%s: fail(%d)\n", __func__, ret);
  858. return ret;
  859. }
  860. }
  861. mdelay(1);
  862. for (i = 0; i < ARRAY_SIZE(cmds); i++) {
  863. ret = mt6360_i2c_write_byte(info, cmds[i], 0x00);
  864. if (ret < 0) {
  865. dprintf(CRITICAL, "%s: fail(%d)\n", __func__, ret);
  866. return ret;
  867. }
  868. }
  869. return mt6360_clr_bit(info, MT6360_PMU_CORE_CTRL1, MT6360_MASK_MREN);
  870. }
  871. static struct mtk_charger_ops mt6360_mchr_ops = {
  872. .dump_register = mt_charger_dump_register,
  873. .enable_charging = mt_charger_enable_charging,
  874. .get_ichg = mt_charger_get_ichg,
  875. .set_ichg = mt_charger_set_ichg_ext,
  876. .get_aicr = mt_charger_get_aicr,
  877. .get_adc = mt_charger_get_adc,
  878. .get_vbus = mt_charger_get_vbus,
  879. .set_aicr = mt_charger_set_aicr_ext,
  880. .set_mivr = mt_charger_set_mivr,
  881. .enable_power_path = mt_charger_enable_power_path,
  882. .reset_pumpx = mt_charger_reset_pumpx,
  883. .enable_wdt = mt_charger_enable_wdt,
  884. .check_charging_mode = mt_charger_check_charging_mode,
  885. .enable_discharge = mt_charger_enable_discharge,
  886. .sw_reset = mt_charger_sw_reset,
  887. };
  888. /* Info of primary charger */
  889. static struct mt6360_pmu_chg_info g_mpci = {
  890. .mchr_info = {
  891. .name = "primary_charger",
  892. .device_id = -1,
  893. .mchr_ops = &mt6360_mchr_ops,
  894. },
  895. .i2c = {
  896. .id = I2C5,
  897. .addr = MT6360_SLAVE_ADDR,
  898. .mode = HS_MODE,
  899. .speed = 400,
  900. .pushpull = true,
  901. },
  902. .i2c_log_level = INFO,
  903. .vid = 0x00,
  904. .iprec = 150,
  905. .ichg = 2000,
  906. .aicr = 500,
  907. .mivr = 4500,
  908. .cv = 4350,
  909. .wkard_en = false,
  910. .ichg_dis_chg = 2000,
  911. .chg_en = true,
  912. };
  913. static int mt6360_chg_init_setting(struct mt6360_pmu_chg_info *info)
  914. {
  915. int ret = 0;
  916. dprintf(CRITICAL, "%s: starts\n", __func__);
  917. ret = mt6360_enable_wdt(info, true);
  918. if (ret < 0) {
  919. dprintf(CRITICAL, "%s: enable wdt failed\n", __func__);
  920. goto out;
  921. }
  922. /* Select input current limit to referenced from AICR */
  923. ret = mt6360_select_input_current_limit(info,
  924. MT6360_IINLMTSEL_AICR);
  925. if (ret < 0) {
  926. dprintf(CRITICAL, "%s: select input current limit failed\n",
  927. __func__);
  928. goto out;
  929. }
  930. mdelay(5);
  931. /* Disable HW iinlimit, use SW */
  932. ret = mt6360_enable_ilim(info, false);
  933. if (ret < 0) {
  934. dprintf(CRITICAL, "%s: disable ilim failed\n", __func__);
  935. goto out;
  936. }
  937. ret = mt_charger_set_iprec(&info->mchr_info, info->iprec);
  938. if (ret < 0) {
  939. dprintf(CRITICAL, "%s: set iprec failed\n", __func__);
  940. goto out;
  941. }
  942. /* Set ichg 500mA for vsys overshoot */
  943. ret = mt_charger_set_ichg(&info->mchr_info, 500);
  944. if (ret < 0) {
  945. dprintf(CRITICAL, "%s: set ichg failed\n", __func__);
  946. goto out;
  947. }
  948. ret = mt_charger_set_aicr(&info->mchr_info, info->aicr);
  949. if (ret < 0) {
  950. dprintf(CRITICAL, "%s: set aicr failed\n", __func__);
  951. goto out;
  952. }
  953. ret = mt_charger_set_mivr(&info->mchr_info, info->mivr);
  954. if (ret < 0) {
  955. dprintf(CRITICAL, "%s: set mivr failed\n", __func__);
  956. goto out;
  957. }
  958. ret = mt6360_set_cv(info, info->cv);
  959. if (ret < 0) {
  960. dprintf(CRITICAL, "%s: set cv failed\n", __func__);
  961. goto out;
  962. }
  963. /* Fix pre-chg/fast-chg current loop not correct */
  964. ret = mt_charger_check_charging_mode(&info->mchr_info);
  965. if (ret < 0) {
  966. dprintf(CRITICAL, "%s: check charging mode fail\n", __func__);
  967. goto out;
  968. }
  969. /* Disable sys drop improvement for download mode */
  970. ret = mt6360_clr_bit(info, MT6360_PMU_CHG_CTRL20, MT6360_MASK_EN_SDI);
  971. if (ret < 0)
  972. dprintf(CRITICAL,
  973. "%s: disable sys drop improvement fail\n", __func__);
  974. out:
  975. return ret;
  976. }
  977. int mt6360_chg_probe(void)
  978. {
  979. int ret = 0;
  980. /* Check primary charger */
  981. if (!mt6360_is_hw_exist(&g_mpci))
  982. return -ENODEV;
  983. dprintf(CRITICAL, "%s: %s\n",
  984. __func__, MT6360_PMU_CHARGER_LK_DRV_VERSION);
  985. ret = mt6360_chg_init_setting(&g_mpci);
  986. if (ret < 0) {
  987. dprintf(CRITICAL, "%s: init setting fail\n", __func__);
  988. return ret;
  989. }
  990. mtk_charger_set_info(&(g_mpci.mchr_info));
  991. return ret;
  992. }
  993. /*
  994. * Revision Note
  995. * 1.0.0
  996. * (1) Initial release
  997. */