mt6370_pmu_charger.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  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) 2015. 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. #include <platform/mt_typedefs.h>
  32. #include <platform/mt_reg_base.h>
  33. #include <platform/errno.h>
  34. #include <platform/mt_i2c.h>
  35. #include <platform/mt_pmic.h>
  36. #include <platform/mt_gpt.h>
  37. #include <platform/mt6370_pmu_charger.h>
  38. #include <platform/mtk_charger_intf.h>
  39. #include <printf.h>
  40. #include <string.h>
  41. #if !defined(CONFIG_POWER_EXT)
  42. #include <platform/upmu_common.h>
  43. #endif
  44. #define MT6370_PMU_CHARGER_LK_DRV_VERSION "1.0.5_MTK"
  45. /* ================= */
  46. /* Internal variable */
  47. /* ================= */
  48. struct mt6370_pmu_charger_info {
  49. struct mtk_charger_info mchr_info;
  50. struct mt_i2c_t i2c;
  51. int i2c_log_level;
  52. unsigned int hidden_mode_cnt;
  53. unsigned char vendor_id;
  54. };
  55. enum mt6370_charging_status {
  56. MT6370_CHG_STATUS_READY = 0,
  57. MT6370_CHG_STATUS_PROGRESS,
  58. MT6370_CHG_STATUS_DONE,
  59. MT6370_CHG_STATUS_FAULT,
  60. MT6370_CHG_STATUS_MAX,
  61. };
  62. /* Charging status name */
  63. static const char *mt6370_chg_status_name[MT6370_CHG_STATUS_MAX] = {
  64. "ready", "progress", "done", "fault",
  65. };
  66. static const unsigned char mt6370_reg_en_hidden_mode[] = {
  67. MT6370_PMU_REG_HIDDENPASCODE1,
  68. MT6370_PMU_REG_HIDDENPASCODE2,
  69. MT6370_PMU_REG_HIDDENPASCODE3,
  70. MT6370_PMU_REG_HIDDENPASCODE4,
  71. };
  72. static const unsigned char mt6370_val_en_hidden_mode[] = {
  73. 0x96, 0x69, 0xC3, 0x3C,
  74. };
  75. static const unsigned char mt6370_val_en_test_mode[] = {
  76. 0x69, 0x96, 0x63, 0x70,
  77. };
  78. /* ======================= */
  79. /* Address & Default value */
  80. /* ======================= */
  81. static const unsigned char mt6370_chg_reg_addr[] = {
  82. MT6370_PMU_REG_CHGCTRL1,
  83. MT6370_PMU_REG_CHGCTRL2,
  84. MT6370_PMU_REG_CHGCTRL3,
  85. MT6370_PMU_REG_CHGCTRL4,
  86. MT6370_PMU_REG_CHGCTRL5,
  87. MT6370_PMU_REG_CHGCTRL6,
  88. MT6370_PMU_REG_CHGCTRL7,
  89. MT6370_PMU_REG_CHGCTRL8,
  90. MT6370_PMU_REG_CHGCTRL9,
  91. MT6370_PMU_REG_CHGCTRL10,
  92. MT6370_PMU_REG_CHGCTRL11,
  93. MT6370_PMU_REG_CHGCTRL12,
  94. MT6370_PMU_REG_CHGCTRL13,
  95. MT6370_PMU_REG_CHGCTRL14,
  96. MT6370_PMU_REG_CHGCTRL15,
  97. MT6370_PMU_REG_CHGCTRL16,
  98. MT6370_PMU_REG_CHGADC,
  99. MT6370_PMU_REG_DEVICETYPE,
  100. MT6370_PMU_REG_QCCTRL1,
  101. MT6370_PMU_REG_QCCTRL2,
  102. MT6370_PMU_REG_QC3P0CTRL1,
  103. MT6370_PMU_REG_QC3P0CTRL2,
  104. MT6370_PMU_REG_USBSTATUS1,
  105. MT6370_PMU_REG_QCSTATUS1,
  106. MT6370_PMU_REG_QCSTATUS2,
  107. MT6370_PMU_REG_CHGPUMP,
  108. MT6370_PMU_REG_CHGCTRL17,
  109. MT6370_PMU_REG_CHGCTRL18,
  110. MT6370_PMU_REG_CHGDIRCHG1,
  111. MT6370_PMU_REG_CHGDIRCHG2,
  112. MT6370_PMU_REG_CHGDIRCHG3,
  113. MT6370_PMU_REG_CHGSTAT,
  114. MT6370_PMU_REG_CHGNTC,
  115. MT6370_PMU_REG_ADCDATAH,
  116. MT6370_PMU_REG_ADCDATAL,
  117. MT6370_PMU_REG_CHGCTRL19,
  118. MT6370_PMU_REG_CHGSTAT1,
  119. MT6370_PMU_REG_CHGSTAT2,
  120. MT6370_PMU_REG_CHGSTAT3,
  121. MT6370_PMU_REG_CHGSTAT4,
  122. MT6370_PMU_REG_CHGSTAT5,
  123. MT6370_PMU_REG_CHGSTAT6,
  124. MT6370_PMU_REG_QCSTAT,
  125. MT6370_PMU_REG_DICHGSTAT,
  126. MT6370_PMU_REG_OVPCTRLSTAT,
  127. };
  128. enum mt6370_iin_limit_sel {
  129. MT6370_IIMLMTSEL_AICR_3250 = 0,
  130. MT6370_IIMLMTSEL_CHR_TYPE,
  131. MT6370_IINLMTSEL_AICR,
  132. MT6370_IINLMTSEL_LOWER_LEVEL, /* lower of above three */
  133. };
  134. /* ========================= */
  135. /* I2C operations */
  136. /* ========================= */
  137. static int mt6370_i2c_write_byte(struct mt6370_pmu_charger_info *info, u8 cmd,
  138. u8 data)
  139. {
  140. unsigned int ret = I2C_OK;
  141. unsigned char write_buf[2] = {cmd, data};
  142. struct mt_i2c_t *i2c = &info->i2c;
  143. ret = i2c_write(i2c, write_buf, 2);
  144. if (ret != I2C_OK)
  145. dprintf(CRITICAL,
  146. "%s: I2CW[0x%02X] = 0x%02X failed, code = %d\n",
  147. __func__, cmd, data, ret);
  148. else
  149. dprintf(info->i2c_log_level, "%s: I2CW[0x%02X] = 0x%02X\n",
  150. __func__, cmd, data);
  151. return ret;
  152. }
  153. static int mt6370_i2c_read_byte(struct mt6370_pmu_charger_info *info, u8 cmd,
  154. u8 *data)
  155. {
  156. int ret = I2C_OK;
  157. u8 ret_data = cmd;
  158. struct mt_i2c_t *i2c = &info->i2c;
  159. ret = i2c_write_read(i2c, &ret_data, 1, 1);
  160. if (ret != I2C_OK)
  161. dprintf(CRITICAL, "%s: I2CR[0x%02X] failed, code = %d\n",
  162. __func__, cmd, ret);
  163. else {
  164. dprintf(info->i2c_log_level, "%s: I2CR[0x%02X] = 0x%02X\n",
  165. __func__, cmd, ret_data);
  166. *data = ret_data;
  167. }
  168. return ret;
  169. }
  170. static int mt6370_i2c_block_write(struct mt6370_pmu_charger_info *info, u8 cmd,
  171. int len, const u8 *data)
  172. {
  173. unsigned char write_buf[len + 1];
  174. struct mt_i2c_t *i2c = &info->i2c;
  175. write_buf[0] = cmd;
  176. memcpy(&write_buf[1], data, len);
  177. return i2c_write(i2c, write_buf, len + 1);
  178. }
  179. static int mt6370_i2c_block_read(struct mt6370_pmu_charger_info *info, u8 cmd,
  180. int len, u8 *data)
  181. {
  182. struct mt_i2c_t *i2c = &info->i2c;
  183. data[0] = cmd;
  184. return i2c_write_read(i2c, data, 1, len);
  185. }
  186. static int mt6370_i2c_test_bit(struct mt6370_pmu_charger_info *info, u8 cmd,
  187. u8 shift)
  188. {
  189. int ret = 0;
  190. u8 data = 0;
  191. ret = mt6370_i2c_read_byte(info, cmd, &data);
  192. if (ret != I2C_OK)
  193. return ret;
  194. ret = data & (1 << shift);
  195. return ret;
  196. }
  197. static int mt6370_i2c_update_bits(struct mt6370_pmu_charger_info *info, u8 cmd,
  198. u8 mask, u8 data)
  199. {
  200. int ret = 0;
  201. u8 reg_data = 0;
  202. ret = mt6370_i2c_read_byte(info, cmd, &reg_data);
  203. if (ret != I2C_OK)
  204. return ret;
  205. reg_data = reg_data & 0xFF;
  206. reg_data &= ~mask;
  207. reg_data |= (data & mask);
  208. return mt6370_i2c_write_byte(info, cmd, reg_data);
  209. }
  210. static inline int mt6370_set_bit(struct mt6370_pmu_charger_info *info, u8 reg,
  211. u8 mask)
  212. {
  213. return mt6370_i2c_update_bits(info, reg, mask, mask);
  214. }
  215. static inline int mt6370_clr_bit(struct mt6370_pmu_charger_info *info, u8 reg,
  216. u8 mask)
  217. {
  218. return mt6370_i2c_update_bits(info, reg, mask, 0x00);
  219. }
  220. /* ================== */
  221. /* internal functions */
  222. /* ================== */
  223. static int mt_charger_set_ichg(struct mtk_charger_info *mchr_info, u32 ichg);
  224. static int mt_charger_set_aicr(struct mtk_charger_info *mchr_info, u32 aicr);
  225. static int mt_charger_set_mivr(struct mtk_charger_info *mchr_info, u32 mivr);
  226. static int mt_charger_get_ichg(struct mtk_charger_info *mchr_info, u32 *ichg);
  227. static int mt_charger_get_aicr(struct mtk_charger_info *mchr_info, u32 *aicr);
  228. static u8 mt6370_find_closest_reg_value(const u32 min, const u32 max,
  229. const u32 step, const u32 num, const u32 target)
  230. {
  231. u32 i = 0, cur_val = 0, next_val = 0;
  232. /* Smaller than minimum supported value, use minimum one */
  233. if (target < min)
  234. return 0;
  235. for (i = 0; i < num - 1; i++) {
  236. cur_val = min + i * step;
  237. next_val = cur_val + step;
  238. if (cur_val > max)
  239. cur_val = max;
  240. if (next_val > max)
  241. next_val = max;
  242. if (target >= cur_val && target < next_val)
  243. return i;
  244. }
  245. /* Greater than maximum supported value, use maximum one */
  246. return num - 1;
  247. }
  248. static u8 mt6370_find_closest_reg_value_via_table(const u32 *value_table,
  249. const u32 table_size, const u32 target_value)
  250. {
  251. u32 i = 0;
  252. /* Smaller than minimum supported value, use minimum one */
  253. if (target_value < value_table[0])
  254. return 0;
  255. for (i = 0; i < table_size - 1; i++) {
  256. if (target_value >= value_table[i] &&
  257. target_value < value_table[i + 1])
  258. return i;
  259. }
  260. /* Greater than maximum supported value, use maximum one */
  261. return table_size - 1;
  262. }
  263. static u32 mt6370_find_closest_real_value(const u32 min, const u32 max,
  264. const u32 step, const u8 reg_val)
  265. {
  266. u32 ret_val = 0;
  267. ret_val = min + reg_val * step;
  268. if (ret_val > max)
  269. ret_val = max;
  270. return ret_val;
  271. }
  272. static int mt6370_enable_hidden_mode(struct mt6370_pmu_charger_info *info,
  273. bool en)
  274. {
  275. int ret = 0;
  276. if (en) {
  277. if (info->hidden_mode_cnt == 0) {
  278. ret = mt6370_i2c_block_write(info,
  279. mt6370_reg_en_hidden_mode[0],
  280. ARRAY_SIZE(mt6370_val_en_hidden_mode),
  281. mt6370_val_en_hidden_mode);
  282. if (ret != I2C_OK)
  283. goto err;
  284. }
  285. info->hidden_mode_cnt++;
  286. } else {
  287. if (info->hidden_mode_cnt == 1) /* last one */
  288. ret = mt6370_i2c_write_byte(info,
  289. mt6370_reg_en_hidden_mode[0], 0x00);
  290. info->hidden_mode_cnt--;
  291. if (ret < 0)
  292. goto err;
  293. }
  294. dprintf(CRITICAL, "%s: en = %d\n", __func__, en);
  295. return 0;
  296. err:
  297. dprintf(CRITICAL, "%s: en = %d fail(%d)\n", __func__, en, ret);
  298. return ret;
  299. }
  300. /* Hardware pin current limit */
  301. static int mt6370_enable_ilim(struct mt6370_pmu_charger_info *info, bool enable)
  302. {
  303. int ret = 0;
  304. dprintf(CRITICAL, "%s: enable ilim = %d\n", __func__, enable);
  305. ret = (enable ? mt6370_set_bit : mt6370_clr_bit)
  306. (info, MT6370_PMU_REG_CHGCTRL3, MT6370_MASK_ILIM_EN);
  307. return ret;
  308. }
  309. /* Select IINLMTSEL to use AICR */
  310. static int mt6370_select_input_current_limit(
  311. struct mt6370_pmu_charger_info *info, enum mt6370_iin_limit_sel sel)
  312. {
  313. int ret = 0;
  314. dprintf(CRITICAL, "%s: select input current limit = %d\n",
  315. __func__, sel);
  316. ret = mt6370_i2c_update_bits(
  317. info,
  318. MT6370_PMU_REG_CHGCTRL2,
  319. MT6370_MASK_IINLMTSEL,
  320. sel << MT6370_SHIFT_IINLMTSEL
  321. );
  322. return ret;
  323. }
  324. static bool mt6370_is_hw_exist(struct mt6370_pmu_charger_info *info)
  325. {
  326. int ret = 0;
  327. u8 vendor_id = 0, revision = 0;
  328. u8 data = 0;
  329. ret = mt6370_i2c_read_byte(info, MT6370_PMU_REG_DEVINFO, &data);
  330. if (ret != I2C_OK)
  331. return false;
  332. vendor_id = data & 0xF0;
  333. revision = data & 0x0F;
  334. if (vendor_id != MT6370_VENDOR_ID && vendor_id != 0xf0) {
  335. dprintf(CRITICAL, "%s: vendor id is incorrect\n", __func__);
  336. return false;
  337. }
  338. dprintf(CRITICAL, "%s: E%d(0x%02X)\n", __func__, revision, revision);
  339. info->mchr_info.device_id = revision;
  340. info->vendor_id = vendor_id;
  341. return true;
  342. }
  343. #if 0
  344. /* Set register's value to default */
  345. static int mt6370_chg_reset_chip(struct mt6370_pmu_charger_info *info)
  346. {
  347. int ret = 0;
  348. dprintf(CRITICAL, "%s: starts\n", __func__);
  349. ret = mt6370_set_bit(info, MT6370_PMU_REG_CORECTRL2,
  350. MT6370_MASK_CHG_RST);
  351. return ret;
  352. }
  353. #endif
  354. static int mt6370_set_battery_voreg(struct mt6370_pmu_charger_info *info,
  355. u32 voreg)
  356. {
  357. int ret = 0;
  358. u8 reg_voreg = 0;
  359. reg_voreg = mt6370_find_closest_reg_value(MT6370_BAT_VOREG_MIN,
  360. MT6370_BAT_VOREG_MAX, MT6370_BAT_VOREG_STEP,
  361. MT6370_BAT_VOREG_NUM, voreg);
  362. dprintf(CRITICAL, "%s: bat voreg = %d\n", __func__, voreg);
  363. ret = mt6370_i2c_update_bits(
  364. info,
  365. MT6370_PMU_REG_CHGCTRL4,
  366. MT6370_MASK_BAT_VOREG,
  367. reg_voreg << MT6370_SHIFT_BAT_VOREG
  368. );
  369. return ret;
  370. }
  371. static int mt6370_enable_wdt(struct mt6370_pmu_charger_info *info,
  372. bool en)
  373. {
  374. int ret = 0;
  375. dprintf(CRITICAL, "%s: en = %d\n", __func__, en);
  376. ret = (en ? mt6370_set_bit : mt6370_clr_bit)
  377. (info, MT6370_PMU_REG_CHGCTRL13, MT6370_MASK_WDT_EN);
  378. return ret;
  379. }
  380. static int mt6370_enable_jeita(struct mt6370_pmu_charger_info *info,
  381. bool en)
  382. {
  383. int ret = 0;
  384. dprintf(CRITICAL, "%s: en = %d\n", __func__, en);
  385. ret = (en ? mt6370_set_bit : mt6370_clr_bit)
  386. (info, MT6370_PMU_REG_CHGCTRL16, MT6370_MASK_JEITA_EN);
  387. return ret;
  388. }
  389. static int mt6370_chg_init_setting(struct mt6370_pmu_charger_info *info)
  390. {
  391. int ret = 0;
  392. dprintf(CRITICAL, "%s: starts\n", __func__);
  393. ret = mt6370_enable_wdt(info, true);
  394. if (ret < 0)
  395. dprintf(CRITICAL, "%s: enable wdt failed\n", __func__);
  396. /* Select input current limit to referenced from AICR */
  397. ret = mt6370_select_input_current_limit(info,
  398. MT6370_IINLMTSEL_AICR);
  399. if (ret < 0)
  400. dprintf(CRITICAL, "%s: select input current limit failed\n",
  401. __func__);
  402. mdelay(5);
  403. /* Disable HW iinlimit, use SW */
  404. ret = mt6370_enable_ilim(info, false);
  405. if (ret < 0)
  406. dprintf(CRITICAL, "%s: disable ilim failed\n", __func__);
  407. ret = mt6370_enable_jeita(info, false);
  408. if (ret < 0)
  409. dprintf(CRITICAL, "%s: disable jeita failed\n", __func__);
  410. ret = mt_charger_set_ichg(&info->mchr_info, 2000);
  411. if (ret < 0)
  412. dprintf(CRITICAL, "%s: set ichg failed\n", __func__);
  413. ret = mt_charger_set_aicr(&info->mchr_info, 500);
  414. if (ret < 0)
  415. dprintf(CRITICAL, "%s: set aicr failed\n", __func__);
  416. ret = mt_charger_set_mivr(&info->mchr_info, 4500);
  417. if (ret < 0)
  418. dprintf(CRITICAL, "%s: set mivr failed\n", __func__);
  419. ret = mt6370_set_battery_voreg(info, 4350);
  420. if (ret < 0)
  421. dprintf(CRITICAL, "%s: set cv failed\n", __func__);
  422. return ret;
  423. }
  424. static int mt6370_get_charging_status(struct mt6370_pmu_charger_info *info,
  425. enum mt6370_charging_status *chg_stat)
  426. {
  427. int ret = 0;
  428. u8 data = 0;
  429. ret = mt6370_i2c_read_byte(info, MT6370_PMU_REG_CHGSTAT, &data);
  430. if (ret != I2C_OK)
  431. return ret;
  432. *chg_stat = (data & MT6370_MASK_CHG_STAT) >> MT6370_SHIFT_CHG_STAT;
  433. return ret;
  434. }
  435. static int mt6370_get_mivr(struct mt6370_pmu_charger_info *info, u32 *mivr)
  436. {
  437. int ret = 0;
  438. u8 reg_mivr = 0;
  439. u8 data = 0;
  440. ret = mt6370_i2c_read_byte(info, MT6370_PMU_REG_CHGCTRL6, &data);
  441. if (ret != I2C_OK)
  442. return ret;
  443. reg_mivr = ((data & MT6370_MASK_MIVR) >> MT6370_SHIFT_MIVR) & 0xFF;
  444. *mivr = mt6370_find_closest_real_value(MT6370_MIVR_MIN, MT6370_MIVR_MAX,
  445. MT6370_MIVR_STEP, reg_mivr);
  446. return ret;
  447. }
  448. static int mt6370_is_charging_enable(struct mt6370_pmu_charger_info *info, bool *enable)
  449. {
  450. int ret = 0;
  451. u8 data = 0;
  452. ret = mt6370_i2c_read_byte(info, MT6370_PMU_REG_CHGCTRL2, &data);
  453. if (ret != I2C_OK)
  454. return ret;
  455. if (((data & MT6370_MASK_CHG_EN) >> MT6370_SHIFT_CHG_EN) & 0xFF)
  456. *enable = true;
  457. else
  458. *enable = false;
  459. return ret;
  460. }
  461. static int mt6370_get_ieoc(struct mt6370_pmu_charger_info *info, u32 *ieoc)
  462. {
  463. int ret = 0;
  464. u8 reg_ieoc = 0;
  465. u8 data = 0;
  466. ret = mt6370_i2c_read_byte(info, MT6370_PMU_REG_CHGCTRL9, &data);
  467. if (ret != I2C_OK)
  468. return ret;
  469. reg_ieoc = (data & MT6370_MASK_IEOC) >> MT6370_SHIFT_IEOC;
  470. *ieoc = mt6370_find_closest_real_value(MT6370_IEOC_MIN, MT6370_IEOC_MAX,
  471. MT6370_IEOC_STEP, reg_ieoc);
  472. return ret;
  473. }
  474. /* =========================================================== */
  475. /* The following is implementation for interface of mt_charger */
  476. /* =========================================================== */
  477. static int mt_charger_dump_register(struct mtk_charger_info *mchr_info)
  478. {
  479. int ret = 0;
  480. u32 i = 0;
  481. u32 ichg = 0, aicr = 0, mivr = 0, ieoc = 0;
  482. bool chg_enable = 0;
  483. enum mt6370_charging_status chg_status = MT6370_CHG_STATUS_READY;
  484. struct mt6370_pmu_charger_info *info =
  485. (struct mt6370_pmu_charger_info *)mchr_info;
  486. u8 data = 0;
  487. ret = mt6370_get_charging_status(info, &chg_status);
  488. if (chg_status == MT6370_CHG_STATUS_FAULT) {
  489. info->i2c_log_level = CRITICAL;
  490. for (i = 0; i < ARRAY_SIZE(mt6370_chg_reg_addr); i++)
  491. ret = mt6370_i2c_read_byte(info, mt6370_chg_reg_addr[i],
  492. &data);
  493. } else
  494. info->i2c_log_level = INFO;
  495. ret = mt_charger_get_ichg(mchr_info, &ichg);
  496. ret = mt6370_get_mivr(info, &mivr);
  497. ret = mt_charger_get_aicr(mchr_info, &aicr);
  498. ret = mt6370_get_ieoc(info, &ieoc);
  499. ret = mt6370_is_charging_enable(info, &chg_enable);
  500. dprintf(CRITICAL,
  501. "%s: ICHG = %dmA, AICR = %dmA, MIVR = %dmV, IEOC = %dmA\n",
  502. __func__, ichg, aicr, mivr, ieoc);
  503. dprintf(CRITICAL, "%s: CHG_EN = %d, CHG_STATUS = %s\n",
  504. __func__, chg_enable, mt6370_chg_status_name[chg_status]);
  505. return ret;
  506. }
  507. static int mt_charger_enable_charging(struct mtk_charger_info *mchr_info,
  508. bool enable)
  509. {
  510. int ret = 0;
  511. struct mt6370_pmu_charger_info *info =
  512. (struct mt6370_pmu_charger_info *)mchr_info;
  513. ret = (enable ? mt6370_set_bit : mt6370_clr_bit)
  514. (info, MT6370_PMU_REG_CHGCTRL2, MT6370_MASK_CHG_EN);
  515. return ret;
  516. }
  517. static int mt_charger_enable_power_path(struct mtk_charger_info *mchr_info,
  518. bool enable)
  519. {
  520. int ret = 0;
  521. struct mt6370_pmu_charger_info *info =
  522. (struct mt6370_pmu_charger_info *)mchr_info;
  523. dprintf(CRITICAL, "%s: enable = %d\n", __func__, enable);
  524. ret = (enable ? mt6370_clr_bit : mt6370_set_bit)
  525. (info, MT6370_PMU_REG_CHGCTRL1, MT6370_MASK_HZ_EN);
  526. return ret;
  527. }
  528. static int mt_charger_set_ichg(struct mtk_charger_info *mchr_info, u32 ichg)
  529. {
  530. int ret = 0;
  531. struct mt6370_pmu_charger_info *info =
  532. (struct mt6370_pmu_charger_info *)mchr_info;
  533. /* Find corresponding reg value */
  534. u8 reg_ichg = mt6370_find_closest_reg_value(MT6370_ICHG_MIN,
  535. MT6370_ICHG_MAX, MT6370_ICHG_STEP, MT6370_ICHG_NUM, ichg);
  536. dprintf(CRITICAL, "%s: ichg = %d\n", __func__, ichg);
  537. ret = mt6370_i2c_update_bits(
  538. info,
  539. MT6370_PMU_REG_CHGCTRL7,
  540. MT6370_MASK_ICHG,
  541. reg_ichg << MT6370_SHIFT_ICHG
  542. );
  543. return ret;
  544. }
  545. static int mt_charger_set_aicr(struct mtk_charger_info *mchr_info, u32 aicr)
  546. {
  547. int ret = 0;
  548. struct mt6370_pmu_charger_info *info =
  549. (struct mt6370_pmu_charger_info *)mchr_info;
  550. /* Find corresponding reg value */
  551. u8 reg_aicr = mt6370_find_closest_reg_value(MT6370_AICR_MIN,
  552. MT6370_AICR_MAX, MT6370_AICR_STEP, MT6370_AICR_NUM, aicr);
  553. dprintf(CRITICAL, "%s: aicr = %d\n", __func__, aicr);
  554. ret = mt6370_i2c_update_bits(
  555. info,
  556. MT6370_PMU_REG_CHGCTRL3,
  557. MT6370_MASK_AICR,
  558. reg_aicr << MT6370_SHIFT_AICR
  559. );
  560. return ret;
  561. }
  562. static int mt_charger_set_mivr(struct mtk_charger_info *mchr_info, u32 mivr)
  563. {
  564. int ret = 0;
  565. struct mt6370_pmu_charger_info *info =
  566. (struct mt6370_pmu_charger_info *)mchr_info;
  567. /* Find corresponding reg value */
  568. u8 reg_mivr = mt6370_find_closest_reg_value(MT6370_MIVR_MIN,
  569. MT6370_MIVR_MAX, MT6370_MIVR_STEP, MT6370_MIVR_NUM, mivr);
  570. dprintf(CRITICAL, "%s: mivr = %d\n", __func__, mivr);
  571. ret = mt6370_i2c_update_bits(
  572. info,
  573. MT6370_PMU_REG_CHGCTRL6,
  574. MT6370_MASK_MIVR,
  575. reg_mivr << MT6370_SHIFT_MIVR
  576. );
  577. return ret;
  578. }
  579. static int mt_charger_get_ichg(struct mtk_charger_info *mchr_info, u32 *ichg)
  580. {
  581. int ret = 0;
  582. u8 reg_ichg = 0;
  583. struct mt6370_pmu_charger_info *info =
  584. (struct mt6370_pmu_charger_info *)mchr_info;
  585. u8 data = 0;
  586. ret = mt6370_i2c_read_byte(info, MT6370_PMU_REG_CHGCTRL7, &data);
  587. if (ret != I2C_OK)
  588. return ret;
  589. reg_ichg = (data & MT6370_MASK_ICHG) >> MT6370_SHIFT_ICHG;
  590. *ichg = mt6370_find_closest_real_value(MT6370_ICHG_MIN, MT6370_ICHG_MAX,
  591. MT6370_ICHG_STEP, reg_ichg);
  592. return ret;
  593. }
  594. static int mt_charger_get_aicr(struct mtk_charger_info *mchr_info, u32 *aicr)
  595. {
  596. int ret = 0;
  597. u8 reg_aicr = 0;
  598. struct mt6370_pmu_charger_info *info =
  599. (struct mt6370_pmu_charger_info *)mchr_info;
  600. u8 data = 0;
  601. ret = mt6370_i2c_read_byte(info, MT6370_PMU_REG_CHGCTRL3, &data);
  602. if (ret != I2C_OK)
  603. return ret;
  604. reg_aicr = (data & MT6370_MASK_AICR) >> MT6370_SHIFT_AICR;
  605. *aicr = mt6370_find_closest_real_value(MT6370_AICR_MIN, MT6370_AICR_MAX,
  606. MT6370_AICR_STEP, reg_aicr);
  607. return ret;
  608. }
  609. static int mt_charger_reset_pumpx(struct mtk_charger_info *mchr_info,
  610. bool reset)
  611. {
  612. int ret = 0;
  613. u32 aicr = 0;
  614. struct mt6370_pmu_charger_info *info =
  615. (struct mt6370_pmu_charger_info *)mchr_info;
  616. mt6370_enable_hidden_mode(info, true);
  617. ret = (reset ? mt6370_clr_bit : mt6370_set_bit)(info, 0x38, 0x80);
  618. aicr = (reset ? 100 : 500);
  619. ret = mt_charger_set_aicr(mchr_info, aicr);
  620. mt6370_enable_hidden_mode(info, false);
  621. return ret;
  622. }
  623. static int mt_charger_enable_wdt(struct mtk_charger_info *mchr_info, bool en)
  624. {
  625. struct mt6370_pmu_charger_info *info =
  626. (struct mt6370_pmu_charger_info *)mchr_info;
  627. return mt6370_enable_wdt(info, en);
  628. }
  629. static int mt_charger_set_bl_driver(struct mtk_charger_info *mchr_info)
  630. {
  631. int ret = 0, tm_try_leave_cnt = 2;
  632. struct mt6370_pmu_charger_info *info =
  633. (struct mt6370_pmu_charger_info *)mchr_info;
  634. u8 pascode[2] = {0};
  635. if (info->vendor_id != 0x80)
  636. return 0;
  637. /* Check if chip reset happened before */
  638. ret = mt6370_i2c_block_read(info, MT6370_PMU_REG_RSTPASCODE1, 2,
  639. pascode);
  640. if (ret != I2C_OK)
  641. dprintf(CRITICAL, "%s: check pas code fail\n", __func__);
  642. else {
  643. dprintf(CRITICAL, "%s: 0x%02X 0x%02X\n", __func__, pascode[0],
  644. pascode[1]);
  645. if (pascode[0] == 0xC5 && pascode[1] == 0x7E) {
  646. dprintf(CRITICAL, "%s: no reset happened\n", __func__);
  647. return 0;
  648. }
  649. }
  650. dprintf(CRITICAL, "%s\n", __func__);
  651. /* Enable I2C reset */
  652. ret = mt6370_set_bit(info, MT6370_PMU_REG_CORECTRL1, 0x80);
  653. if (ret != I2C_OK) {
  654. dprintf(CRITICAL, "%s: en i2c reset fail\n", __func__);
  655. return -EINVAL;
  656. }
  657. /* Enter test mode */
  658. ret = mt6370_i2c_block_write(info, 0xF0,
  659. ARRAY_SIZE(mt6370_val_en_test_mode), mt6370_val_en_test_mode);
  660. if (ret != I2C_OK) {
  661. dprintf(CRITICAL, "%s: enter test mode fail\n", __func__);
  662. return ret;
  663. }
  664. mdelay(1);
  665. ret = mt6370_i2c_write_byte(info, 0xFF, 0x69);
  666. if (ret != I2C_OK) {
  667. dprintf(CRITICAL, "%s: enter bl/db part fail\n", __func__);
  668. goto out;
  669. }
  670. mdelay(1);
  671. ret = mt6370_i2c_update_bits(info, 0x34, 0xC0, 0xC0);
  672. if (ret != I2C_OK) {
  673. dprintf(CRITICAL, "%s: modify bl driver fail\n", __func__);
  674. goto out;
  675. }
  676. mdelay(1);
  677. ret = mt6370_i2c_update_bits(info, 0x37, 0xC0, 0x00);
  678. if (ret != I2C_OK)
  679. dprintf(CRITICAL, "%s: modify db driver fail\n", __func__);
  680. mdelay(1);
  681. out:
  682. do {
  683. ret = mt6370_i2c_write_byte(info, 0xF0, 0x00);
  684. if (ret != I2C_OK) {
  685. dprintf(CRITICAL, "%s: leave tm fail\n", __func__);
  686. tm_try_leave_cnt--;
  687. } else
  688. break;
  689. } while (tm_try_leave_cnt > 0);
  690. /* Disable I2C reset */
  691. ret = mt6370_clr_bit(info, MT6370_PMU_REG_CORECTRL1, 0x80);
  692. if (ret != I2C_OK)
  693. dprintf(CRITICAL, "%s: disable i2c reset fail\n", __func__);
  694. return ret;
  695. }
  696. static struct mtk_charger_ops mt6370_mchr_ops = {
  697. .dump_register = mt_charger_dump_register,
  698. .enable_charging = mt_charger_enable_charging,
  699. .get_ichg = mt_charger_get_ichg,
  700. .set_ichg = mt_charger_set_ichg,
  701. .set_aicr = mt_charger_set_aicr,
  702. .set_mivr = mt_charger_set_mivr,
  703. .enable_power_path = mt_charger_enable_power_path,
  704. .get_aicr = mt_charger_get_aicr,
  705. .reset_pumpx = mt_charger_reset_pumpx,
  706. .enable_wdt = mt_charger_enable_wdt,
  707. .set_bl_driver = mt_charger_set_bl_driver,
  708. };
  709. /* Info of primary charger */
  710. static struct mt6370_pmu_charger_info g_mt6370_pmu_charger_info = {
  711. .mchr_info = {
  712. .name = "primary_charger",
  713. .device_id = -1,
  714. .mchr_ops = &mt6370_mchr_ops,
  715. },
  716. .i2c = {
  717. .id = I2C5,
  718. .addr = MT6370_SLAVE_ADDR,
  719. .mode = HS_MODE,
  720. .speed = 3400,
  721. .pushpull = true,
  722. },
  723. .i2c_log_level = INFO,
  724. .hidden_mode_cnt = 0,
  725. .vendor_id = 0x00,
  726. };
  727. int mt6370_chg_probe(void)
  728. {
  729. int ret = 0;
  730. /* Check primary charger */
  731. if (mt6370_is_hw_exist(&g_mt6370_pmu_charger_info)) {
  732. dprintf(CRITICAL, "%s: %s\n", __func__,
  733. MT6370_PMU_CHARGER_LK_DRV_VERSION);
  734. #if 0
  735. ret = mt6370_chg_reset_chip(&g_mt6370_pmu_charger_info);
  736. #endif
  737. ret = mt6370_chg_init_setting(&g_mt6370_pmu_charger_info);
  738. mtk_charger_set_info(&(g_mt6370_pmu_charger_info.mchr_info));
  739. }
  740. return ret;
  741. }
  742. /*
  743. * Revision Note
  744. * 1.0.5
  745. * (1) Add bl-desense workaround
  746. *
  747. * 1.0.4
  748. * (1) Add enable_wdt interface
  749. *
  750. * 1.0.3
  751. * (1) Disable/Enable spk mode for pe+
  752. *
  753. * 1.0.2
  754. * (1) Modify sequence of enable_ilim & select iinlimit
  755. * and add 5ms delay between these two ops
  756. *
  757. * 1.0.1
  758. * (1) Disable JEITA
  759. * (2) Enable WDT
  760. *
  761. * 1.0.0
  762. * (1) Initial release
  763. */