battery_meter_hal.c 27 KB

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