battery_meter_hal.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. /*
  2. * Copyright (C) 2015 MediaTek Inc.
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/delay.h>
  14. #include <asm/div64.h>
  15. #include <mt-plat/upmu_common.h>
  16. #include <mt-plat/battery_meter_hal.h>
  17. #include <mach/mt_battery_meter.h>
  18. #include <mach/mt_pmic.h>
  19. #include <mt-plat/battery_meter.h>
  20. #include <mt-plat/mt_boot_reason.h>
  21. /* ============================================================ // */
  22. /* define */
  23. /* ============================================================ // */
  24. #define STATUS_OK 0
  25. #define STATUS_UNSUPPORTED -1
  26. #define VOLTAGE_FULL_RANGE 1800
  27. #define ADC_PRECISE 32768 /* 12 bits */
  28. #define UNIT_FGCURRENT (158122) /* 158.122 uA */
  29. /* ============================================================ // */
  30. /* global variable */
  31. /* ============================================================ // */
  32. signed int chip_diff_trim_value_4_0 = 0;
  33. signed int chip_diff_trim_value = 0; /* unit = 0.1 */
  34. signed int g_hw_ocv_tune_value = 0;
  35. kal_bool g_fg_is_charging = 0;
  36. /* ============================================================ // */
  37. /* function prototype */
  38. /* ============================================================ // */
  39. /* ============================================================ // */
  40. /* extern variable */
  41. /* ============================================================ // */
  42. /* ============================================================ // */
  43. /* extern function */
  44. /* ============================================================ // */
  45. /*extern unsigned int upmu_get_reg_value(unsigned int reg);
  46. extern int IMM_GetOneChannelValue(int dwChannel, int data[4], int *rawdata);
  47. extern int IMM_IsAdcInitReady(void);
  48. extern U32 pmic_config_interface(U32 RegNum, U32 val, U32 MASK, U32 SHIFT);
  49. extern U32 pmic_read_interface(U32 RegNum, U32 *val, U32 MASK, U32 SHIFT);
  50. extern unsigned int get_pmic_mt6325_cid(void);*/
  51. /* ============================================================ // */
  52. void get_hw_chip_diff_trim_value(void)
  53. {
  54. #if defined(CONFIG_POWER_EXT)
  55. #else
  56. #if 1
  57. signed int reg_val = 0;
  58. reg_val = upmu_get_reg_value(0xCB8);
  59. chip_diff_trim_value_4_0 = (reg_val >> 7) & 0x001F; /* chip_diff_trim_value_4_0 = (reg_val>>10)&0x001F; */
  60. bm_print(BM_LOG_CRTI, "[Chip_Trim] Reg[0xCB8]=0x%x, chip_diff_trim_value_4_0=%d\n", reg_val,
  61. chip_diff_trim_value_4_0);
  62. #else
  63. bm_print(BM_LOG_FULL, "[Chip_Trim] need check reg number\n");
  64. #endif
  65. switch (chip_diff_trim_value_4_0) {
  66. case 0:
  67. chip_diff_trim_value = 1000;
  68. break;
  69. case 1:
  70. chip_diff_trim_value = 1005;
  71. break;
  72. case 2:
  73. chip_diff_trim_value = 1010;
  74. break;
  75. case 3:
  76. chip_diff_trim_value = 1015;
  77. break;
  78. case 4:
  79. chip_diff_trim_value = 1020;
  80. break;
  81. case 5:
  82. chip_diff_trim_value = 1025;
  83. break;
  84. case 6:
  85. chip_diff_trim_value = 1030;
  86. break;
  87. case 7:
  88. chip_diff_trim_value = 1036;
  89. break;
  90. case 8:
  91. chip_diff_trim_value = 1041;
  92. break;
  93. case 9:
  94. chip_diff_trim_value = 1047;
  95. break;
  96. case 10:
  97. chip_diff_trim_value = 1052;
  98. break;
  99. case 11:
  100. chip_diff_trim_value = 1058;
  101. break;
  102. case 12:
  103. chip_diff_trim_value = 1063;
  104. break;
  105. case 13:
  106. chip_diff_trim_value = 1069;
  107. break;
  108. case 14:
  109. chip_diff_trim_value = 1075;
  110. break;
  111. case 15:
  112. chip_diff_trim_value = 1081;
  113. break;
  114. case 31:
  115. chip_diff_trim_value = 995;
  116. break;
  117. case 30:
  118. chip_diff_trim_value = 990;
  119. break;
  120. case 29:
  121. chip_diff_trim_value = 985;
  122. break;
  123. case 28:
  124. chip_diff_trim_value = 980;
  125. break;
  126. case 27:
  127. chip_diff_trim_value = 975;
  128. break;
  129. case 26:
  130. chip_diff_trim_value = 970;
  131. break;
  132. case 25:
  133. chip_diff_trim_value = 966;
  134. break;
  135. case 24:
  136. chip_diff_trim_value = 961;
  137. break;
  138. case 23:
  139. chip_diff_trim_value = 956;
  140. break;
  141. case 22:
  142. chip_diff_trim_value = 952;
  143. break;
  144. case 21:
  145. chip_diff_trim_value = 947;
  146. break;
  147. case 20:
  148. chip_diff_trim_value = 943;
  149. break;
  150. case 19:
  151. chip_diff_trim_value = 938;
  152. break;
  153. case 18:
  154. chip_diff_trim_value = 934;
  155. break;
  156. case 17:
  157. chip_diff_trim_value = 930;
  158. break;
  159. default:
  160. bm_print(BM_LOG_FULL, "[Chip_Trim] Invalid value(%d)\n", chip_diff_trim_value_4_0);
  161. break;
  162. }
  163. bm_print(BM_LOG_CRTI, "[Chip_Trim] chip_diff_trim_value=%d\n", chip_diff_trim_value);
  164. #endif
  165. }
  166. signed int use_chip_trim_value(signed int not_trim_val)
  167. {
  168. #if defined(CONFIG_POWER_EXT)
  169. return not_trim_val;
  170. #else
  171. signed int ret_val = 0;
  172. ret_val = ((not_trim_val * chip_diff_trim_value) / 1000);
  173. bm_print(BM_LOG_FULL, "[use_chip_trim_value] %d -> %d\n", not_trim_val, ret_val);
  174. return ret_val;
  175. #endif
  176. }
  177. int get_hw_ocv(void)
  178. {
  179. #if defined(CONFIG_POWER_EXT)
  180. return 4001;
  181. bm_print(BM_LOG_CRTI, "[get_hw_ocv] TBD\n");
  182. #else
  183. signed int adc_result_reg = 0;
  184. signed int adc_result = 0;
  185. signed int r_val_temp = 3; /* MT6325 use 2, old chip use 4 */
  186. #if defined(SWCHR_POWER_PATH)
  187. adc_result_reg = pmic_get_register_value(PMIC_AUXADC_ADC_OUT_WAKEUP_SWCHR);
  188. /* mt6325_upmu_get_rg_adc_out_wakeup_swchr(); */
  189. adc_result = (adc_result_reg * r_val_temp * VOLTAGE_FULL_RANGE) / ADC_PRECISE;
  190. bm_print(BM_LOG_CRTI, "[oam] get_hw_ocv (swchr) : adc_result_reg=%d, adc_result=%d\n",
  191. adc_result_reg, adc_result);
  192. #else
  193. adc_result_reg = pmic_get_register_value(PMIC_AUXADC_ADC_OUT_WAKEUP_PCHR);
  194. /* mt6325_upmu_get_rg_adc_out_wakeup_pchr(); */
  195. adc_result = (adc_result_reg * r_val_temp * VOLTAGE_FULL_RANGE) / ADC_PRECISE;
  196. bm_print(BM_LOG_CRTI, "[oam] get_hw_ocv (pchr) : adc_result_reg=%d, adc_result=%d\n",
  197. adc_result_reg, adc_result);
  198. #endif
  199. adc_result += g_hw_ocv_tune_value;
  200. return adc_result;
  201. #endif
  202. }
  203. /* ============================================================// */
  204. #if defined(CONFIG_POWER_EXT)
  205. /* */
  206. #else
  207. static void dump_nter(void)
  208. {
  209. bm_print(BM_LOG_CRTI, "[dump_nter] mt6328_upmu_get_fg_nter_29_16 = 0x%x\r\n",
  210. pmic_get_register_value(PMIC_FG_NTER_29_16));
  211. bm_print(BM_LOG_CRTI, "[dump_nter] mt6328_upmu_get_fg_nter_15_00 = 0x%x\r\n",
  212. pmic_get_register_value(PMIC_FG_NTER_15_00));
  213. }
  214. static void dump_car(void)
  215. {
  216. bm_print(BM_LOG_CRTI, "[dump_car] upmu_get_fg_car_31_16 = 0x%x\r\n",
  217. pmic_get_register_value(PMIC_FG_CAR_31_16));
  218. bm_print(BM_LOG_CRTI, "[dump_car] upmu_get_fg_car_15_00 = 0x%x\r\n",
  219. pmic_get_register_value(PMIC_FG_CAR_15_00));
  220. }
  221. static unsigned int fg_get_data_ready_status(void)
  222. {
  223. unsigned int ret = 0;
  224. unsigned int temp_val = 0;
  225. ret = pmic_read_interface(MT6328_FGADC_CON0, &temp_val, 0xFFFF, 0x0);
  226. bm_print(BM_LOG_FULL, "[fg_get_data_ready_status] Reg[0x%x]=0x%x\r\n", MT6328_FGADC_CON0,
  227. temp_val);
  228. temp_val =
  229. (temp_val & (MT6328_PMIC_FG_LATCHDATA_ST_MASK << MT6328_PMIC_FG_LATCHDATA_ST_SHIFT)) >>
  230. MT6328_PMIC_FG_LATCHDATA_ST_SHIFT;
  231. return temp_val;
  232. }
  233. #endif
  234. static signed int fgauge_read_current(void *data);
  235. static signed int fgauge_initialization(void *data)
  236. {
  237. #if defined(CONFIG_POWER_EXT)
  238. /* */
  239. #else
  240. unsigned int ret = 0;
  241. signed int current_temp = 0;
  242. int m = 0;
  243. get_hw_chip_diff_trim_value();
  244. /* 1. HW initialization */
  245. /* FGADC clock is 32768Hz from RTC */
  246. /* Enable FGADC in current mode at 32768Hz with auto-calibration */
  247. /* (1) Enable VA2 */
  248. /* (2) Enable FGADC clock for digital */
  249. pmic_set_register_value(PMIC_RG_FGADC_ANA_CK_PDN, 0); /* mt6325_upmu_set_rg_fgadc_ana_ck_pdn(0); */
  250. pmic_set_register_value(PMIC_RG_FGADC_DIG_CK_PDN, 0); /* mt6325_upmu_set_rg_fgadc_dig_ck_pdn(0); */
  251. /* (3) Set current mode, auto-calibration mode and 32KHz clock source */
  252. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x0028, 0x00FF, 0x0);
  253. /* (4) Enable FGADC */
  254. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x0029, 0x00FF, 0x0);
  255. /* reset HW FG */
  256. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x7100, 0xFF00, 0x0);
  257. bm_print(BM_LOG_CRTI, "******** [fgauge_initialization] reset HW FG!\n");
  258. /* set FG_OSR */
  259. ret = pmic_config_interface(MT6328_FGADC_CON11, 0x8, 0xF, 0x0);
  260. bm_print(BM_LOG_CRTI, "[fgauge_initialization] Reg[0x%x]=0x%x\n", MT6328_FGADC_CON11,
  261. upmu_get_reg_value(MT6328_FGADC_CON11));
  262. /* make sure init finish */
  263. m = 0;
  264. while (current_temp == 0) {
  265. fgauge_read_current(&current_temp);
  266. m++;
  267. if (m > 1000) {
  268. bm_print(BM_LOG_CRTI, "[fgauge_initialization] timeout!\r\n");
  269. break;
  270. }
  271. }
  272. bm_print(BM_LOG_CRTI, "******** [fgauge_initialization] Done!\n");
  273. #endif
  274. return STATUS_OK;
  275. }
  276. static signed int fgauge_read_current(void *data)
  277. {
  278. #if defined(CONFIG_POWER_EXT)
  279. *(signed int *) (data) = 0;
  280. #else
  281. unsigned short uvalue16 = 0;
  282. signed int dvalue = 0;
  283. int m = 0;
  284. long long Temp_Value = 0;
  285. signed int Current_Compensate_Value = 0;
  286. unsigned int ret = 0;
  287. /* HW Init */
  288. /* (1) i2c_write (0x60, 0xC8, 0x01); // Enable VA2 */
  289. /* (2) i2c_write (0x61, 0x15, 0x00); // Enable FGADC clock for digital */
  290. /* (3) i2c_write (0x61, 0x69, 0x28); // Set current mode, auto-calibration mode and 32KHz clock source */
  291. /* (4) i2c_write (0x61, 0x69, 0x29); // Enable FGADC */
  292. /* Read HW Raw Data */
  293. /* (1) Set READ command */
  294. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x0200, 0xFF00, 0x0);
  295. /* (2) Keep i2c read when status = 1 (0x06) */
  296. m = 0;
  297. while (fg_get_data_ready_status() == 0) {
  298. m++;
  299. if (m > 1000) {
  300. bm_print(BM_LOG_FULL,
  301. "[fgauge_read_current] fg_get_data_ready_status timeout 1 !\r\n");
  302. break;
  303. }
  304. }
  305. /* (3) Read FG_CURRENT_OUT[15:08] */
  306. /* (4) Read FG_CURRENT_OUT[07:00] */
  307. uvalue16 = pmic_get_register_value(PMIC_FG_CURRENT_OUT); /* mt6325_upmu_get_fg_current_out(); */
  308. bm_print(BM_LOG_FULL, "[fgauge_read_current] : FG_CURRENT = %x\r\n", uvalue16);
  309. /* (5) (Read other data) */
  310. /* (6) Clear status to 0 */
  311. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x0800, 0xFF00, 0x0);
  312. /* (7) Keep i2c read when status = 0 (0x08) */
  313. /* while ( fg_get_sw_clear_status() != 0 ) */
  314. m = 0;
  315. while (fg_get_data_ready_status() != 0) {
  316. m++;
  317. if (m > 1000) {
  318. bm_print(BM_LOG_FULL,
  319. "[fgauge_read_current] fg_get_data_ready_status timeout 2 !\r\n");
  320. break;
  321. }
  322. }
  323. /* (8) Recover original settings */
  324. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x0000, 0xFF00, 0x0);
  325. /* calculate the real world data */
  326. dvalue = (unsigned int) uvalue16;
  327. if (dvalue == 0) {
  328. Temp_Value = (long long) dvalue;
  329. g_fg_is_charging = KAL_FALSE;
  330. } else if (dvalue > 32767) {/* > 0x8000 */
  331. Temp_Value = (long long) (dvalue - 65535);
  332. Temp_Value = Temp_Value - (Temp_Value * 2);
  333. g_fg_is_charging = KAL_FALSE;
  334. } else {
  335. Temp_Value = (long long) dvalue;
  336. g_fg_is_charging = KAL_TRUE;
  337. }
  338. Temp_Value = Temp_Value * UNIT_FGCURRENT;
  339. do_div(Temp_Value, 100000);
  340. dvalue = (unsigned int) Temp_Value;
  341. if (g_fg_is_charging == KAL_TRUE) {
  342. bm_print(BM_LOG_FULL, "[fgauge_read_current] current(charging) = %d mA\r\n",
  343. dvalue);
  344. } else {
  345. bm_print(BM_LOG_FULL, "[fgauge_read_current] current(discharging) = %d mA\r\n",
  346. dvalue);
  347. }
  348. /* Auto adjust value */
  349. if (batt_meter_cust_data.r_fg_value != 20) {
  350. bm_print(BM_LOG_FULL,
  351. "[fgauge_read_current] Auto adjust value due to the Rfg is %d\n Ori current=%d, ",
  352. batt_meter_cust_data.r_fg_value, dvalue);
  353. dvalue = (dvalue * 20) / batt_meter_cust_data.r_fg_value;
  354. bm_print(BM_LOG_FULL, "[fgauge_read_current] new current=%d\n", dvalue);
  355. }
  356. /* K current */
  357. if (batt_meter_cust_data.r_fg_board_slope != batt_meter_cust_data.r_fg_board_base) {
  358. dvalue =
  359. ((dvalue * batt_meter_cust_data.r_fg_board_base) +
  360. (batt_meter_cust_data.r_fg_board_slope / 2)) /
  361. batt_meter_cust_data.r_fg_board_slope;
  362. }
  363. /* current compensate */
  364. if (g_fg_is_charging == KAL_TRUE)
  365. dvalue = dvalue + Current_Compensate_Value;
  366. else
  367. dvalue = dvalue - Current_Compensate_Value;
  368. bm_print(BM_LOG_FULL, "[fgauge_read_current] ori current=%d\n", dvalue);
  369. dvalue = ((dvalue * batt_meter_cust_data.car_tune_value) / 100);
  370. dvalue = use_chip_trim_value(dvalue);
  371. bm_print(BM_LOG_FULL, "[fgauge_read_current] final current=%d (ratio=%d)\n", dvalue,
  372. batt_meter_cust_data.car_tune_value);
  373. *(signed int *) (data) = dvalue;
  374. #endif
  375. return STATUS_OK;
  376. }
  377. signed int fgauge_read_IM_current(void *data)
  378. {
  379. #if defined(CONFIG_POWER_EXT)
  380. *(signed int *) (data) = 0;
  381. #else
  382. unsigned short uvalue16 = 0;
  383. signed int dvalue = 0;
  384. /*int m = 0;*/
  385. long long Temp_Value = 0;
  386. signed int Current_Compensate_Value = 0;
  387. /*unsigned int ret = 0;*/
  388. uvalue16 = pmic_get_register_value(PMIC_FG_R_CURR);
  389. bm_print(BM_LOG_FULL, "[fgauge_read_IM_current] : FG_CURRENT = %x\r\n", uvalue16);
  390. /* calculate the real world data */
  391. dvalue = (unsigned int) uvalue16;
  392. if (dvalue == 0) {
  393. Temp_Value = (long long) dvalue;
  394. g_fg_is_charging = KAL_FALSE;
  395. } else if (dvalue > 32767) {/* > 0x8000 */
  396. Temp_Value = (long long) (dvalue - 65535);
  397. Temp_Value = Temp_Value - (Temp_Value * 2);
  398. g_fg_is_charging = KAL_FALSE;
  399. } else {
  400. Temp_Value = (long long) dvalue;
  401. g_fg_is_charging = KAL_TRUE;
  402. }
  403. Temp_Value = Temp_Value * UNIT_FGCURRENT;
  404. do_div(Temp_Value, 100000);
  405. dvalue = (unsigned int) Temp_Value;
  406. if (g_fg_is_charging == KAL_TRUE) {
  407. bm_print(BM_LOG_FULL, "[fgauge_read_IM_current] current(charging) = %d mA\r\n",
  408. dvalue);
  409. } else {
  410. bm_print(BM_LOG_FULL, "[fgauge_read_IM_current] current(discharging) = %d mA\r\n",
  411. dvalue);
  412. }
  413. /* Auto adjust value */
  414. if (batt_meter_cust_data.r_fg_value != 20) {
  415. bm_print(BM_LOG_FULL,
  416. "[fgauge_read_IM_current] Auto adjust value due to the Rfg is %d\n Ori current=%d, ",
  417. batt_meter_cust_data.r_fg_value, dvalue);
  418. dvalue = (dvalue * 20) / batt_meter_cust_data.r_fg_value;
  419. bm_print(BM_LOG_FULL, "[fgauge_read_IM_current] new current=%d\n", dvalue);
  420. }
  421. /* K current */
  422. if (batt_meter_cust_data.r_fg_board_slope != batt_meter_cust_data.r_fg_board_base) {
  423. dvalue =
  424. ((dvalue * batt_meter_cust_data.r_fg_board_base) +
  425. (batt_meter_cust_data.r_fg_board_slope / 2)) /
  426. batt_meter_cust_data.r_fg_board_slope;
  427. }
  428. /* current compensate */
  429. if (g_fg_is_charging == KAL_TRUE)
  430. dvalue = dvalue + Current_Compensate_Value;
  431. else
  432. dvalue = dvalue - Current_Compensate_Value;
  433. bm_print(BM_LOG_FULL, "[fgauge_read_IM_current] ori current=%d\n", dvalue);
  434. dvalue = ((dvalue * batt_meter_cust_data.car_tune_value) / 100);
  435. dvalue = use_chip_trim_value(dvalue);
  436. bm_print(BM_LOG_FULL, "[fgauge_read_IM_current] final current=%d (ratio=%d)\n", dvalue,
  437. batt_meter_cust_data.car_tune_value);
  438. *(signed int *) (data) = dvalue;
  439. #endif
  440. return STATUS_OK;
  441. }
  442. static signed int fgauge_read_current_sign(void *data)
  443. {
  444. *(kal_bool *) (data) = g_fg_is_charging;
  445. return STATUS_OK;
  446. }
  447. static signed int fgauge_read_columb(void *data);
  448. signed int fgauge_set_columb_interrupt_internal(void *data, int reset)
  449. {
  450. #if defined(CONFIG_POWER_EXT)
  451. return STATUS_OK;
  452. #else
  453. unsigned int uvalue32_CAR = 0;
  454. unsigned int uvalue32_CAR_MSB = 0;
  455. signed short upperbound = 0, lowbound = 0;
  456. signed short pcar = 0;
  457. signed short m;
  458. unsigned int car = *(unsigned int *) (data);
  459. unsigned int ret = 0;
  460. unsigned short *plow, *phigh, *pori;
  461. bm_print(BM_LOG_FULL, "fgauge_set_columb_interrupt_internal car=%d\n", car);
  462. plow = (unsigned short *) &lowbound;
  463. phigh = (unsigned short *) &upperbound;
  464. pori = (unsigned short *) &uvalue32_CAR;
  465. if (car == 0) {
  466. pmic_set_register_value(PMIC_RG_INT_EN_FG_BAT_H, 0);
  467. pmic_set_register_value(PMIC_RG_INT_EN_FG_BAT_L, 0);
  468. bm_print(BM_LOG_FULL,
  469. "[fgauge_set_columb_interrupt] low:[0xcae]=0x%x high:[0xcb0]=0x%x %d %d \r\n",
  470. pmic_get_register_value(PMIC_FG_BLTR),
  471. pmic_get_register_value(PMIC_FG_BFTR),
  472. pmic_get_register_value(PMIC_RG_INT_EN_FG_BAT_L),
  473. pmic_get_register_value(PMIC_RG_INT_EN_FG_BAT_H));
  474. return STATUS_OK;
  475. }
  476. if (car == 0x1ffff) {
  477. pmic_set_register_value(PMIC_RG_INT_EN_FG_BAT_H, 1);
  478. pmic_set_register_value(PMIC_RG_INT_EN_FG_BAT_L, 1);
  479. bm_print(BM_LOG_FULL,
  480. "[fgauge_set_columb_interrupt] low:[0xcae]=0x%x high:[0xcb0]=0x%x %d %d\r\n",
  481. pmic_get_register_value(PMIC_FG_BLTR),
  482. pmic_get_register_value(PMIC_FG_BFTR),
  483. pmic_get_register_value(PMIC_RG_INT_EN_FG_BAT_L),
  484. pmic_get_register_value(PMIC_RG_INT_EN_FG_BAT_H));
  485. return STATUS_OK;
  486. }
  487. /* HW Init */
  488. /* (1) i2c_write (0x60, 0xC8, 0x01); // Enable VA2 */
  489. /* (2) i2c_write (0x61, 0x15, 0x00); // Enable FGADC clock for digital */
  490. /* (3) i2c_write (0x61, 0x69, 0x28); // Set current mode, auto-calibration mode and 32KHz clock source */
  491. /* (4) i2c_write (0x61, 0x69, 0x29); // Enable FGADC */
  492. /* Read HW Raw Data */
  493. /* (1) Set READ command */
  494. if (reset == 0)
  495. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x0200, 0xFF00, 0x0);
  496. else
  497. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x7300, 0xFF00, 0x0);
  498. /* (2) Keep i2c read when status = 1 (0x06) */
  499. m = 0;
  500. while (fg_get_data_ready_status() == 0) {
  501. m++;
  502. if (m > 1000) {
  503. bm_print(BM_LOG_FULL,
  504. "[fgauge_set_columb_interrupt] fg_get_data_ready_status timeout 1 !");
  505. break;
  506. }
  507. }
  508. /* (3) Read FG_CURRENT_OUT[28:14] */
  509. /* (4) Read FG_CURRENT_OUT[31] */
  510. uvalue32_CAR = (pmic_get_register_value(PMIC_FG_CAR_15_00)) >> 14;
  511. uvalue32_CAR |= ((pmic_get_register_value(PMIC_FG_CAR_31_16)) & 0x7FFF) << 2;
  512. uvalue32_CAR_MSB = (pmic_get_register_value(PMIC_FG_CAR_31_16) & 0x8000) >> 15;
  513. bm_print(BM_LOG_FULL,
  514. "[fgauge_set_columb_interrupt] FG_CAR = 0x%x uvalue32_CAR_MSB:0x%x\r\n",
  515. uvalue32_CAR, uvalue32_CAR_MSB);
  516. uvalue32_CAR = uvalue32_CAR & 0x7fff;
  517. if (uvalue32_CAR_MSB == 1)
  518. uvalue32_CAR = uvalue32_CAR | 0x8000;
  519. bm_print(BM_LOG_FULL,
  520. "[fgauge_set_columb_interrupt] FG_CAR = 0x%x:%d msb=0x%x car=0x%x:%d FG_CAR2:0x%x:%d \r\n ",
  521. uvalue32_CAR, uvalue32_CAR, uvalue32_CAR_MSB, car, car, *pori, *pori);
  522. /* restore use_chip_trim_value() */
  523. car = ((car * 1000) / chip_diff_trim_value);
  524. car = ((car * 100) / batt_meter_cust_data.car_tune_value);
  525. car = ((car * batt_meter_cust_data.r_fg_value) / 20);
  526. car = car * 8000;
  527. car = car * 10;
  528. car = car + 5;
  529. car = car * 10;
  530. car = car / 35986;
  531. pcar = (signed short) car;
  532. upperbound = *pori;
  533. lowbound = *pori;
  534. /*
  535. if(uvalue32_CAR_MSB==1)
  536. {
  537. upperbound=(signed short)(upperbound-upperbound*2);
  538. lowbound=(signed short)(lowbound-lowbound*2);
  539. }
  540. */
  541. bm_print(BM_LOG_FULL,
  542. "[fgauge_set_columb_interrupt] upper = 0x%x:%d low=0x%x:%d car=0x%x:%d\r\n",
  543. upperbound, upperbound, lowbound, lowbound, pcar, pcar);
  544. upperbound = upperbound + pcar;
  545. lowbound = lowbound - pcar;
  546. bm_print(BM_LOG_FULL,
  547. "[fgauge_set_columb_interrupt]final upper = 0x%x:%d low=0x%x:%d car=0x%x:%d\r\n",
  548. upperbound, upperbound, lowbound, lowbound, pcar, pcar);
  549. pmic_set_register_value(PMIC_FG_BLTR, *plow);
  550. pmic_set_register_value(PMIC_FG_BFTR, *phigh);
  551. /*msleep(1);*/usleep_range(1000, 2000);
  552. pmic_set_register_value(PMIC_RG_INT_EN_FG_BAT_H, 1);
  553. pmic_set_register_value(PMIC_RG_INT_EN_FG_BAT_L, 1);
  554. bm_print(BM_LOG_FULL,
  555. "[fgauge_set_columb_interrupt] low:[0xcae]=0x%x high:[0xcb0]=0x%x\r\n",
  556. pmic_get_register_value(PMIC_FG_BLTR), pmic_get_register_value(PMIC_FG_BFTR));
  557. return STATUS_OK;
  558. #endif
  559. }
  560. static signed int fgauge_set_columb_interrupt(void *data)
  561. {
  562. return fgauge_set_columb_interrupt_internal(data, 0);
  563. }
  564. static signed int fgauge_read_columb_internal(void *data, int reset, int precise)
  565. {
  566. #if defined(CONFIG_POWER_EXT)
  567. *(signed int *) (data) = 0;
  568. #else
  569. unsigned int uvalue32_CAR = 0;
  570. unsigned int uvalue32_CAR_MSB = 0;
  571. signed int dvalue_CAR = 0;
  572. int m = 0;
  573. long long Temp_Value = 0;
  574. unsigned int ret = 0;
  575. /* HW Init */
  576. /* (1) i2c_write (0x60, 0xC8, 0x01); // Enable VA2 */
  577. /* (2) i2c_write (0x61, 0x15, 0x00); // Enable FGADC clock for digital */
  578. /* (3) i2c_write (0x61, 0x69, 0x28); // Set current mode, auto-calibration mode and 32KHz clock source */
  579. /* (4) i2c_write (0x61, 0x69, 0x29); // Enable FGADC */
  580. /* Read HW Raw Data */
  581. /* (1) Set READ command */
  582. if (reset == 0)
  583. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x0200, 0xFF00, 0x0);
  584. else
  585. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x7300, 0xFF00, 0x0);
  586. /* (2) Keep i2c read when status = 1 (0x06) */
  587. m = 0;
  588. while (fg_get_data_ready_status() == 0) {
  589. m++;
  590. if (m > 1000) {
  591. bm_print(BM_LOG_FULL,
  592. "[fgauge_read_columb_internal] fg_get_data_ready_status timeout 1 !\r\n");
  593. break;
  594. }
  595. }
  596. /* (3) Read FG_CURRENT_OUT[28:14] */
  597. /* (4) Read FG_CURRENT_OUT[31] */
  598. uvalue32_CAR = (pmic_get_register_value(PMIC_FG_CAR_15_00)) >> 14;
  599. uvalue32_CAR |= ((pmic_get_register_value(PMIC_FG_CAR_31_16)) & 0x7FFF) << 2;
  600. uvalue32_CAR_MSB = (pmic_get_register_value(PMIC_FG_CAR_31_16) & 0x8000) >> 15;
  601. bm_print(BM_LOG_FULL, "[fgauge_read_columb_internal] FG_CAR = 0x%x\r\n", uvalue32_CAR);
  602. bm_print(BM_LOG_FULL, "[fgauge_read_columb_internal] uvalue32_CAR_MSB = 0x%x\r\n",
  603. uvalue32_CAR_MSB);
  604. /* (5) (Read other data) */
  605. /* (6) Clear status to 0 */
  606. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x0800, 0xFF00, 0x0);
  607. /* (7) Keep i2c read when status = 0 (0x08) */
  608. /* while ( fg_get_sw_clear_status() != 0 ) */
  609. m = 0;
  610. while (fg_get_data_ready_status() != 0) {
  611. m++;
  612. if (m > 1000) {
  613. bm_print(BM_LOG_FULL,
  614. "[fgauge_read_columb_internal] fg_get_data_ready_status timeout 2 !\r\n");
  615. break;
  616. }
  617. }
  618. /* (8) Recover original settings */
  619. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x0000, 0xFF00, 0x0);
  620. /* calculate the real world data */
  621. dvalue_CAR = (signed int) uvalue32_CAR;
  622. if (uvalue32_CAR == 0) {
  623. Temp_Value = 0;
  624. } else if (uvalue32_CAR == 0x1ffff) {
  625. Temp_Value = 0;
  626. } else if (uvalue32_CAR_MSB == 0x1) {
  627. /* dis-charging */
  628. Temp_Value = (long long) (dvalue_CAR - 0x1ffff); /* keep negative value */
  629. Temp_Value = Temp_Value - (Temp_Value * 2);
  630. } else {
  631. /* charging */
  632. Temp_Value = (long long) dvalue_CAR;
  633. }
  634. #if 0
  635. Temp_Value = (((Temp_Value * 35986) / 10) + (5)) / 10; /* [28:14]'s LSB=359.86 uAh */
  636. #else
  637. Temp_Value = Temp_Value * 35986;
  638. do_div(Temp_Value, 10);
  639. Temp_Value = Temp_Value + 5;
  640. do_div(Temp_Value, 10);
  641. #endif
  642. #if 0
  643. dvalue_CAR = Temp_Value / 1000; /* mAh */
  644. #else
  645. /* dvalue_CAR = (Temp_Value/8)/1000; //mAh, due to FG_OSR=0x8 */
  646. if (precise == 0) {
  647. do_div(Temp_Value, 8);
  648. do_div(Temp_Value, 1000);
  649. } else {
  650. do_div(Temp_Value, 8);
  651. do_div(Temp_Value, 100);
  652. }
  653. if (uvalue32_CAR_MSB == 0x1)
  654. dvalue_CAR = (signed int) (Temp_Value - (Temp_Value * 2)); /* keep negative value */
  655. else
  656. dvalue_CAR = (signed int) Temp_Value;
  657. #endif
  658. bm_print(BM_LOG_FULL, "[fgauge_read_columb_internal] dvalue_CAR = %d\r\n", dvalue_CAR);
  659. /* #if (OSR_SELECT_7 == 1) */
  660. /* Auto adjust value */
  661. if (batt_meter_cust_data.r_fg_value != 20) {
  662. bm_print(BM_LOG_FULL,
  663. "[fgauge_read_columb_internal] Auto adjust value deu to the Rfg is %d\n Ori CAR=%d, ",
  664. batt_meter_cust_data.r_fg_value, dvalue_CAR);
  665. dvalue_CAR = (dvalue_CAR * 20) / batt_meter_cust_data.r_fg_value;
  666. bm_print(BM_LOG_FULL, "[fgauge_read_columb_internal] new CAR=%d\n", dvalue_CAR);
  667. }
  668. dvalue_CAR = ((dvalue_CAR * batt_meter_cust_data.car_tune_value) / 100);
  669. dvalue_CAR = use_chip_trim_value(dvalue_CAR);
  670. bm_print(BM_LOG_FULL, "[fgauge_read_columb_internal] final dvalue_CAR = %d\r\n",
  671. dvalue_CAR);
  672. dump_nter();
  673. dump_car();
  674. *(signed int *) (data) = dvalue_CAR;
  675. #endif
  676. return STATUS_OK;
  677. }
  678. static signed int fgauge_read_columb(void *data)
  679. {
  680. return fgauge_read_columb_internal(data, 0, 0);
  681. }
  682. static signed int fgauge_read_columb_accurate(void *data)
  683. {
  684. return fgauge_read_columb_internal(data, 0, 1);
  685. }
  686. static signed int fgauge_hw_reset(void *data)
  687. {
  688. #if defined(CONFIG_POWER_EXT)
  689. /* */
  690. #else
  691. volatile unsigned int val_car = 1;
  692. unsigned int val_car_temp = 1;
  693. unsigned int ret = 0;
  694. bm_print(BM_LOG_FULL, "[fgauge_hw_reset] : Start \r\n");
  695. while (val_car != 0x0) {
  696. ret = pmic_config_interface(MT6328_FGADC_CON0, 0x7100, 0xFF00, 0x0);
  697. fgauge_read_columb_internal(&val_car_temp, 1, 0);
  698. val_car = val_car_temp;
  699. bm_print(BM_LOG_FULL, "#");
  700. }
  701. bm_print(BM_LOG_FULL, "[fgauge_hw_reset] : End \r\n");
  702. #endif
  703. return STATUS_OK;
  704. }
  705. static signed int read_adc_v_bat_sense(void *data)
  706. {
  707. #if defined(CONFIG_POWER_EXT)
  708. *(signed int *) (data) = 4201;
  709. #else
  710. #if defined(SWCHR_POWER_PATH)
  711. *(signed int *) (data) =
  712. PMIC_IMM_GetOneChannelValue(MT6328_AUX_ISENSE_AP, *(signed int *) (data), 1);
  713. #else
  714. *(signed int *) (data) =
  715. PMIC_IMM_GetOneChannelValue(MT6328_AUX_BATSNS_AP, *(signed int *) (data), 1);
  716. #endif
  717. #endif
  718. return STATUS_OK;
  719. }
  720. static signed int read_adc_v_i_sense(void *data)
  721. {
  722. #if defined(CONFIG_POWER_EXT)
  723. *(signed int *) (data) = 4202;
  724. #else
  725. #if defined(SWCHR_POWER_PATH)
  726. *(signed int *) (data) =
  727. PMIC_IMM_GetOneChannelValue(MT6328_AUX_BATSNS_AP, *(signed int *) (data), 1);
  728. #else
  729. *(signed int *) (data) =
  730. PMIC_IMM_GetOneChannelValue(MT6328_AUX_ISENSE_AP, *(signed int *) (data), 1);
  731. #endif
  732. #endif
  733. return STATUS_OK;
  734. }
  735. static signed int read_adc_v_bat_temp(void *data)
  736. {
  737. #if defined(CONFIG_POWER_EXT)
  738. *(signed int *) (data) = 0;
  739. #else
  740. #if defined(MTK_PCB_TBAT_FEATURE)
  741. /* no HW support */
  742. #else
  743. bm_print(BM_LOG_FULL,
  744. "[read_adc_v_bat_temp] return PMIC_IMM_GetOneChannelValue(4,times,1);\n");
  745. *(signed int *) (data) =
  746. PMIC_IMM_GetOneChannelValue(MT6328_AUX_BATON_AP, *(signed int *) (data), 1);
  747. #endif
  748. #endif
  749. return STATUS_OK;
  750. }
  751. static signed int read_adc_v_charger(void *data)
  752. {
  753. #if defined(CONFIG_POWER_EXT)
  754. *(signed int *) (data) = 5001;
  755. #else
  756. signed int val;
  757. val = PMIC_IMM_GetOneChannelValue(MT6328_AUX_VCDT_AP, *(signed int *) (data), 1);
  758. val =
  759. (((batt_meter_cust_data.r_charger_1 +
  760. batt_meter_cust_data.r_charger_2) * 100 * val) / batt_meter_cust_data.r_charger_2) /
  761. 100;
  762. *(signed int *) (data) = val;
  763. #endif
  764. return STATUS_OK;
  765. }
  766. static signed int read_hw_ocv(void *data)
  767. {
  768. #if defined(CONFIG_POWER_EXT)
  769. *(signed int *) (data) = 3999;
  770. #else
  771. #if 0
  772. *(signed int *) (data) = PMIC_IMM_GetOneChannelValue(AUX_BATSNS_AP, 5, 1);
  773. bm_print(BM_LOG_CRTI, "[read_hw_ocv] By SW AUXADC for bring up\n");
  774. #else
  775. *(signed int *) (data) = get_hw_ocv();
  776. #endif
  777. #endif
  778. return STATUS_OK;
  779. }
  780. static signed int read_is_hw_ocv_ready(void *data)
  781. {
  782. #if defined(CONFIG_POWER_EXT)
  783. *(signed int *) (data) = 0;
  784. #else
  785. #if defined(SWCHR_POWER_PATH)
  786. *(signed int *) (data) = pmic_get_register_value(PMIC_AUXADC_ADC_RDY_WAKEUP_SWCHR);
  787. bm_err("[read_is_hw_ocv_ready] is_hw_ocv_ready(SWCHR) %d\n", *(signed int *) (data));
  788. pmic_set_register_value(PMIC_AUXADC_ADC_RDY_WAKEUP_CLR, 1);
  789. mdelay(1);
  790. pmic_set_register_value(PMIC_AUXADC_ADC_RDY_WAKEUP_CLR, 0);
  791. #else
  792. *(signed int *) (data) = pmic_get_register_value(PMIC_AUXADC_ADC_RDY_WAKEUP_PCHR);
  793. bm_err("[read_is_hw_ocv_ready] is_hw_ocv_ready(PCHR) %d\n", *(signed int *) (data));
  794. pmic_set_register_value(PMIC_AUXADC_ADC_RDY_WAKEUP_CLR, 1);
  795. mdelay(1);
  796. pmic_set_register_value(PMIC_AUXADC_ADC_RDY_WAKEUP_CLR, 0);
  797. #endif
  798. #endif
  799. return STATUS_OK;
  800. }
  801. static signed int dump_register_fgadc(void *data)
  802. {
  803. return STATUS_OK;
  804. }
  805. static signed int read_battery_plug_out_status(void *data)
  806. {
  807. *(signed int *) (data) = is_battery_remove_pmic();
  808. return STATUS_OK;
  809. }
  810. static signed int(*bm_func[BATTERY_METER_CMD_NUMBER]) (void *data);
  811. signed int bm_ctrl_cmd(BATTERY_METER_CTRL_CMD cmd, void *data)
  812. {
  813. signed int status = STATUS_UNSUPPORTED;
  814. static signed int init = -1;
  815. if (init == -1) {
  816. init = 0;
  817. bm_func[BATTERY_METER_CMD_HW_FG_INIT] = fgauge_initialization;
  818. bm_func[BATTERY_METER_CMD_GET_HW_FG_CURRENT] = fgauge_read_current;
  819. bm_func[BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN] = fgauge_read_current_sign;
  820. bm_func[BATTERY_METER_CMD_GET_HW_FG_CAR] = fgauge_read_columb;
  821. bm_func[BATTERY_METER_CMD_HW_RESET] = fgauge_hw_reset;
  822. bm_func[BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE] = read_adc_v_bat_sense;
  823. bm_func[BATTERY_METER_CMD_GET_ADC_V_I_SENSE] = read_adc_v_i_sense;
  824. bm_func[BATTERY_METER_CMD_GET_ADC_V_BAT_TEMP] = read_adc_v_bat_temp;
  825. bm_func[BATTERY_METER_CMD_GET_ADC_V_CHARGER] = read_adc_v_charger;
  826. bm_func[BATTERY_METER_CMD_GET_HW_OCV] = read_hw_ocv;
  827. bm_func[BATTERY_METER_CMD_DUMP_REGISTER] = dump_register_fgadc;
  828. bm_func[BATTERY_METER_CMD_SET_COLUMB_INTERRUPT] = fgauge_set_columb_interrupt;
  829. bm_func[BATTERY_METER_CMD_GET_BATTERY_PLUG_STATUS] = read_battery_plug_out_status;
  830. bm_func[BATTERY_METER_CMD_GET_HW_FG_CAR_ACT] = fgauge_read_columb_accurate;
  831. bm_func[BATTERY_METER_CMD_GET_IS_HW_OCV_READY] = read_is_hw_ocv_ready;
  832. }
  833. if (cmd < BATTERY_METER_CMD_NUMBER) {
  834. if (bm_func[cmd] != NULL)
  835. status = bm_func[cmd] (data);
  836. } else
  837. return STATUS_UNSUPPORTED;
  838. return status;
  839. }
  840. signed int pmic_is_battery_plugout(void)
  841. {
  842. int is_battery_plugout;
  843. int pmic_strup_pwroff_seq_en = pmic_get_register_value(PMIC_STRUP_PWROFF_SEQ_EN);
  844. int uvlo_rstb_status = pmic_get_register_value(PMIC_UVLO_RSTB_STATUS);
  845. int is_long_press = (get_boot_reason() == BR_POWER_KEY ? 1 : 0);
  846. int is_wdt_reboot = pmic_get_register_value(PMIC_WDTRSTB_STATUS);
  847. pmic_set_register_value(PMIC_UVLO_RSTB_STATUS, 1);
  848. if (pmic_strup_pwroff_seq_en) {
  849. if (uvlo_rstb_status)
  850. is_battery_plugout = 0;
  851. else {
  852. if (is_long_press)
  853. is_battery_plugout = 0;
  854. else {
  855. if (is_wdt_reboot)
  856. is_battery_plugout = 0;
  857. else
  858. is_battery_plugout = 1;
  859. }
  860. }
  861. } else
  862. is_battery_plugout = 1;
  863. bm_err("[pmic_is_battery_plugout] [%d] %d, %d, %d, %d\n",
  864. is_battery_plugout, pmic_strup_pwroff_seq_en, uvlo_rstb_status, is_long_press, is_wdt_reboot);
  865. return is_battery_plugout;
  866. }