import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / power / mediatek / battery_meter.c
CommitLineData
6fa3eb70
S
1#include <linux/init.h> /* For init/exit macros */
2#include <linux/module.h> /* For MODULE_ marcros */
3#include <linux/fs.h>
4#include <linux/device.h>
5#include <linux/interrupt.h>
6#include <linux/spinlock.h>
7#include <linux/platform_device.h>
8
9#include <linux/device.h>
10#include <linux/kdev_t.h>
11#include <linux/fs.h>
12#include <linux/cdev.h>
13#include <linux/delay.h>
14#include <linux/mutex.h>
15#include <linux/kthread.h>
16#include <linux/proc_fs.h>
17#include <linux/rtc.h>
18#include <linux/time.h>
19#include <linux/slab.h>
20#ifdef CONFIG_OF
21#include <linux/of.h>
22#include <linux/of_irq.h>
23#include <linux/of_address.h>
24#endif
25
26#include <asm/uaccess.h>
27#include <mach/mt_typedefs.h>
28#include <mach/hardware.h>
29#include <mach/mt_boot.h>
30#include <mach/mt_boot_reason.h>
31
32#include <mach/battery_common.h>
33#include <mach/battery_meter.h>
34#include <mach/battery_meter_hal.h>
35#include "cust_battery_meter.h"
36#include "cust_battery_meter_table.h"
37#include "cust_pmic.h"
38#include "mach/mtk_rtc.h"
39
40/* ============================================================ // */
41/* define */
42/* ============================================================ // */
43#define PROFILE_SIZE 4
44
45static DEFINE_MUTEX(FGADC_mutex);
46
47#ifdef CUST_CAPACITY_OCV2CV_TRANSFORM
48#define TEMP_AVERAGE_SIZE 30 /* Temperature window size */
49#define step_of_Qmax 54 //54 mah
50#endif
51int Enable_FGADC_LOG = 1;
52
53/* ============================================================ // */
54/* global variable */
55/* ============================================================ // */
56BATTERY_METER_CONTROL battery_meter_ctrl = NULL;
57
6fa3eb70
S
58kal_bool gFG_Is_Charging = KAL_FALSE;
59kal_int32 g_auxadc_solution = 0;
60U32 g_spm_timer = 600;
61bool bat_spm_timeout = false;
62U32 _g_bat_sleep_total_time = NORMAL_WAKEUP_PERIOD;
63#ifdef MTK_ENABLE_AGING_ALGORITHM
64U32 suspend_time = 0;
65#endif
66kal_int32 g_booting_vbat = 0;
67static U32 temperature_change = 1;
68
69#ifdef CUST_CAPACITY_OCV2CV_TRANSFORM
70static kal_int32 g_currentfactor = 100; //100%
71static kal_bool g_USE_UI_SOC = KAL_TRUE;
72#endif
73
74
75/* ///////////////////////////////////////////////////////////////////////////////////////// */
76/* // PMIC AUXADC Related Variable */
77/* ///////////////////////////////////////////////////////////////////////////////////////// */
78int g_R_BAT_SENSE = R_BAT_SENSE;
79int g_R_I_SENSE = R_I_SENSE;
80int g_R_CHARGER_1 = R_CHARGER_1;
81int g_R_CHARGER_2 = R_CHARGER_2;
82
83int fg_qmax_update_for_aging_flag = 1;
84
85/* HW FG */
86kal_int32 gFG_DOD0 = 0;
87kal_int32 gFG_DOD1 = 0;
88kal_int32 gFG_columb = 0;
89kal_int32 gFG_voltage = 0;
90kal_int32 gFG_current = 0;
91kal_int32 gFG_capacity = 0;
92kal_int32 gFG_capacity_by_c = 0;
93kal_int32 gFG_capacity_by_c_init = 0;
94kal_int32 gFG_capacity_by_v = 0;
95kal_int32 gFG_capacity_by_v_init = 0;
96kal_int32 gFG_temp = 100;
97kal_int32 gFG_resistance_bat = 0;
98kal_int32 gFG_compensate_value = 0;
99kal_int32 gFG_ori_voltage = 0;
100kal_int32 gFG_BATT_CAPACITY = 0;
101kal_int32 gFG_voltage_init = 0;
102kal_int32 gFG_current_auto_detect_R_fg_total = 0;
103kal_int32 gFG_current_auto_detect_R_fg_count = 0;
104kal_int32 gFG_current_auto_detect_R_fg_result = 0;
105kal_int32 gFG_15_vlot = 3700;
106kal_int32 gFG_BATT_CAPACITY_init_high_current = 1200;
107kal_int32 gFG_BATT_CAPACITY_aging = 1200;
108
109/* voltage mode */
110kal_int32 gfg_percent_check_point = 50;
111kal_int32 volt_mode_update_timer = 0;
112kal_int32 volt_mode_update_time_out = 6; /* 1mins */
113
114/* EM */
115kal_int32 g_fg_dbg_bat_volt = 0;
116kal_int32 g_fg_dbg_bat_current = 0;
117kal_int32 g_fg_dbg_bat_zcv = 0;
118kal_int32 g_fg_dbg_bat_temp = 0;
119kal_int32 g_fg_dbg_bat_r = 0;
120kal_int32 g_fg_dbg_bat_car = 0;
121kal_int32 g_fg_dbg_bat_qmax = 0;
122kal_int32 g_fg_dbg_d0 = 0;
123kal_int32 g_fg_dbg_d1 = 0;
124kal_int32 g_fg_dbg_percentage = 0;
125kal_int32 g_fg_dbg_percentage_fg = 0;
126kal_int32 g_fg_dbg_percentage_voltmode = 0;
127
128kal_int32 FGvbatVoltageBuffer[FG_VBAT_AVERAGE_SIZE];
129kal_int32 FGbatteryIndex = 0;
130kal_int32 FGbatteryVoltageSum = 0;
131kal_int32 gFG_voltage_AVG = 0;
132kal_int32 gFG_vbat_offset = 0;
133#ifdef Q_MAX_BY_CURRENT
134kal_int32 FGCurrentBuffer[FG_CURRENT_AVERAGE_SIZE];
135kal_int32 FGCurrentIndex = 0;
136kal_int32 FGCurrentSum = 0;
137kal_int32 gFG_current_AVG = 0;
138#endif
139kal_int32 g_tracking_point = CUST_TRACKING_POINT;
140kal_int32 g_rtc_fg_soc = 0;
141kal_int32 g_I_SENSE_offset = 0;
142
143/* SW FG */
144kal_int32 oam_v_ocv_init = 0;
145kal_int32 oam_v_ocv_1 = 0;
146kal_int32 oam_v_ocv_2 = 0;
147kal_int32 oam_r_1 = 0;
148kal_int32 oam_r_2 = 0;
149kal_int32 oam_d0 = 0;
150kal_int32 oam_i_ori = 0;
151kal_int32 oam_i_1 = 0;
152kal_int32 oam_i_2 = 0;
153kal_int32 oam_car_1 = 0;
154kal_int32 oam_car_2 = 0;
155kal_int32 oam_d_1 = 1;
156kal_int32 oam_d_2 = 1;
157kal_int32 oam_d_3 = 1;
158kal_int32 oam_d_3_pre = 0;
159kal_int32 oam_d_4 = 0;
160kal_int32 oam_d_4_pre = 0;
161kal_int32 oam_d_5 = 0;
162kal_int32 oam_init_i = 0;
163kal_int32 oam_run_i = 0;
164kal_int32 d5_count = 0;
165kal_int32 d5_count_time = 60;
166kal_int32 d5_count_time_rate = 1;
167kal_int32 g_d_hw_ocv = 0;
168kal_int32 g_vol_bat_hw_ocv = 0;
169kal_int32 g_hw_ocv_before_sleep = 0;
170struct timespec g_rtc_time_before_sleep, xts_before_sleep;
171kal_int32 g_sw_vbat_temp = 0;
172struct timespec last_oam_run_time;
173
174/*[BUGFIX]-Add-BEGIN by TCTSZ.pingao.yang, 4/15/2015, pr-975290, add standby current */
175static kal_int32 suspend_current = DEFAUL_SUSPEND_CURRENT;
176static kal_int32 g_sleep_fg_soc = 0;
177static kal_int32 g_sleep_fg_ui_soc = 0;
178static kal_int32 resume_count = 0;
179static kal_int32 after_sleep_time = 0;
180static kal_int32 before_sleep_time = 0;
181/*[BUGFIX]-Add-END by TCTSZ.pingao.yang */
182
183/* aging mechanism */
184#ifdef MTK_ENABLE_AGING_ALGORITHM
185
186static kal_int32 aging_ocv_1 = 0;
187static kal_int32 aging_ocv_2 = 0;
188static kal_int32 aging_car_1 = 0;
189static kal_int32 aging_car_2 = 0;
190static kal_int32 aging_dod_1 = 0;
191static kal_int32 aging_dod_2 = 0;
192#ifdef MD_SLEEP_CURRENT_CHECK
193static kal_int32 columb_before_sleep = 0x123456;
194#endif
195//static time_t aging_resume_time_1 = 0;
196//static time_t aging_resume_time_2 = 0;
197
198#ifndef SELF_DISCHARGE_CHECK_THRESHOLD
199#define SELF_DISCHARGE_CHECK_THRESHOLD 10
200#endif
201
202#ifndef OCV_RECOVER_TIME
203#define OCV_RECOVER_TIME 2100
204#endif
205
206#ifndef DOD1_ABOVE_THRESHOLD
207#define DOD1_ABOVE_THRESHOLD 30
208#endif
209
210#ifndef DOD2_BELOW_THRESHOLD
211#define DOD2_BELOW_THRESHOLD 70
212#endif
213
214#ifndef MIN_DOD_DIFF_THRESHOLD
215#define MIN_DOD_DIFF_THRESHOLD 60
216#endif
217
218#ifndef MIN_AGING_FACTOR
219#define MIN_AGING_FACTOR 90
220#endif
221
222#endif /* aging mechanism */
223
224/* battery info */
225#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
226
227kal_int32 gFG_battery_cycle = 0;
228kal_int32 gFG_aging_factor = 100;
229kal_int32 gFG_columb_sum = 0;
230kal_int32 gFG_pre_columb_count = 0;
231
232kal_int32 gFG_max_voltage = 0;
233kal_int32 gFG_min_voltage = 10000;
234kal_int32 gFG_max_current = 0;
235kal_int32 gFG_min_current = 0;
236kal_int32 gFG_max_temperature = -20;
237kal_int32 gFG_min_temperature = 100;
238
239#endif /* battery info */
240
241extern char* saved_command_line;
242/* Temperature window size */
243#define TEMP_AVERAGE_SIZE 30
244
245kal_bool gFG_Is_offset_init = KAL_FALSE;
246
247#ifdef MTK_MULTI_BAT_PROFILE_SUPPORT
248extern int IMM_GetOneChannelValue_Cali(int Channel, int *voltage);
249kal_uint32 g_fg_battery_id = 0;
250
251#ifdef MTK_GET_BATTERY_ID_BY_AUXADC
252void fgauge_get_profile_id(void)
253{
254 int id_volt = 0;
255 int id = 0;
256 int ret = 0;
257
258 ret = IMM_GetOneChannelValue_Cali(BATTERY_ID_CHANNEL_NUM, &id_volt);
259 if (ret != 0)
260 bm_print(BM_LOG_CRTI, "[fgauge_get_profile_id]id_volt read fail\n");
261 else
262 bm_print(BM_LOG_CRTI, "[fgauge_get_profile_id]id_volt = %d\n", id_volt);
263
264 if ((sizeof(g_battery_id_voltage) / sizeof(kal_int32)) != TOTAL_BATTERY_NUMBER) {
265 bm_print(BM_LOG_CRTI, "[fgauge_get_profile_id]error! voltage range incorrect!\n");
266 return;
267 }
268
269 for (id = 0; id < TOTAL_BATTERY_NUMBER; id++) {
270 if (id_volt < g_battery_id_voltage[id]) {
271 g_fg_battery_id = id;
272 break;
273 } else if (g_battery_id_voltage[id] == -1) {
274 g_fg_battery_id = TOTAL_BATTERY_NUMBER - 1;
275 }
276 }
277
278 bm_print(BM_LOG_CRTI, "[fgauge_get_profile_id]Battery id (%d)\n", g_fg_battery_id);
279}
280#elif defined(MTK_GET_BATTERY_ID_BY_GPIO)
281void fgauge_get_profile_id(void)
282{
283 g_fg_battery_id = 0;
284}
285#else
286void fgauge_get_profile_id(void)
287{
288 g_fg_battery_id = 0;
289}
290#endif
291#endif
292
293/* ============================================================ // */
294/* function prototype */
295/* ============================================================ // */
296
297/* ============================================================ // */
298/* extern variable */
299/* ============================================================ // */
300
301/* ============================================================ // */
302/* extern function */
303/* ============================================================ // */
304/* extern int get_rtc_spare_fg_value(void); */
305/* extern unsigned long rtc_read_hw_time(void); */
306
307
308
309/* ============================================================ // */
310int get_r_fg_value(void)
311{
312 return (R_FG_VALUE + CUST_R_FG_OFFSET);
313}
314
315#ifdef MTK_MULTI_BAT_PROFILE_SUPPORT
316int BattThermistorConverTemp(int Res)
317{
318 int i = 0;
319 int RES1 = 0, RES2 = 0;
320 int TBatt_Value = -200, TMP1 = 0, TMP2 = 0;
321
322 BATT_TEMPERATURE *batt_temperature_table = &Batt_Temperature_Table[g_fg_battery_id];
323 if (Res >= batt_temperature_table[0].TemperatureR) {
324 TBatt_Value = -20;
325 } else if (Res <= batt_temperature_table[16].TemperatureR) {
326 TBatt_Value = 60;
327 } else {
328 RES1 = batt_temperature_table[0].TemperatureR;
329 TMP1 = batt_temperature_table[0].BatteryTemp;
330
331 for (i = 0; i <= 16; i++) {
332 if (Res >= batt_temperature_table[i].TemperatureR) {
333 RES2 = batt_temperature_table[i].TemperatureR;
334 TMP2 = batt_temperature_table[i].BatteryTemp;
335 break;
336 } else {
337 RES1 = batt_temperature_table[i].TemperatureR;
338 TMP1 = batt_temperature_table[i].BatteryTemp;
339 }
340 }
341
342 TBatt_Value = (((Res - RES2) * TMP1) + ((RES1 - Res) * TMP2)) / (RES1 - RES2);
343 }
344
345 return TBatt_Value;
346}
347
348kal_int32 fgauge_get_Q_max(kal_int16 temperature)
349{
350 kal_int32 ret_Q_max = 0;
351 kal_int32 low_temperature = 0, high_temperature = 0;
352 kal_int32 low_Q_max = 0, high_Q_max = 0;
353
354 if (temperature <= TEMPERATURE_T1) {
355 low_temperature = (-10);
356 low_Q_max = g_Q_MAX_NEG_10[g_fg_battery_id];
357 high_temperature = TEMPERATURE_T1;
358 high_Q_max = g_Q_MAX_POS_0[g_fg_battery_id];
359
360 if (temperature < low_temperature) {
361 temperature = low_temperature;
362 }
363 } else if (temperature <= TEMPERATURE_T2) {
364 low_temperature = TEMPERATURE_T1;
365 low_Q_max = g_Q_MAX_POS_0[g_fg_battery_id];
366 high_temperature = TEMPERATURE_T2;
367 high_Q_max = g_Q_MAX_POS_25[g_fg_battery_id];
368
369 if (temperature < low_temperature) {
370 temperature = low_temperature;
371 }
372 } else {
373 low_temperature = TEMPERATURE_T2;
374 low_Q_max = g_Q_MAX_POS_25[g_fg_battery_id];
375 high_temperature = TEMPERATURE_T3;
376 high_Q_max = g_Q_MAX_POS_50[g_fg_battery_id];
377
378 if (temperature > high_temperature) {
379 temperature = high_temperature;
380 }
381 }
382
383 ret_Q_max = low_Q_max + (((temperature - low_temperature) * (high_Q_max - low_Q_max)
384 ) / (high_temperature - low_temperature)
385 );
386
387 bm_print(BM_LOG_FULL, "[fgauge_get_Q_max] Q_max = %d\r\n", ret_Q_max);
388
389 return ret_Q_max;
390}
391
392
393kal_int32 fgauge_get_Q_max_high_current(kal_int16 temperature)
394{
395 kal_int32 ret_Q_max = 0;
396 kal_int32 low_temperature = 0, high_temperature = 0;
397 kal_int32 low_Q_max = 0, high_Q_max = 0;
398
399 if (temperature <= TEMPERATURE_T1) {
400 low_temperature = (-10);
401 low_Q_max = g_Q_MAX_NEG_10_H_CURRENT[g_fg_battery_id];
402 high_temperature = TEMPERATURE_T1;
403 high_Q_max = g_Q_MAX_POS_0_H_CURRENT[g_fg_battery_id];
404
405 if (temperature < low_temperature) {
406 temperature = low_temperature;
407 }
408 } else if (temperature <= TEMPERATURE_T2) {
409 low_temperature = TEMPERATURE_T1;
410 low_Q_max = g_Q_MAX_POS_0_H_CURRENT[g_fg_battery_id];
411 high_temperature = TEMPERATURE_T2;
412 high_Q_max = g_Q_MAX_POS_25_H_CURRENT[g_fg_battery_id];
413
414 if (temperature < low_temperature) {
415 temperature = low_temperature;
416 }
417 } else {
418 low_temperature = TEMPERATURE_T2;
419 low_Q_max = g_Q_MAX_POS_25_H_CURRENT[g_fg_battery_id];
420 high_temperature = TEMPERATURE_T3;
421 high_Q_max = g_Q_MAX_POS_50_H_CURRENT[g_fg_battery_id];
422
423 if (temperature > high_temperature) {
424 temperature = high_temperature;
425 }
426 }
427
428 ret_Q_max = low_Q_max + (((temperature - low_temperature) * (high_Q_max - low_Q_max)
429 ) / (high_temperature - low_temperature)
430 );
431
432 bm_print(BM_LOG_FULL, "[fgauge_get_Q_max_high_current] Q_max = %d\r\n", ret_Q_max);
433
434 return ret_Q_max;
435}
436
437#else
438
439int BattThermistorConverTemp(int Res)
440{
441 int i = 0;
442 int RES1 = 0, RES2 = 0;
443 int TBatt_Value = -200, TMP1 = 0, TMP2 = 0;
444
445 if (Res >= Batt_Temperature_Table[0].TemperatureR) {
446 TBatt_Value = -20;
447 } else if (Res <= Batt_Temperature_Table[16].TemperatureR) {
448 TBatt_Value = 60;
449 } else {
450 RES1 = Batt_Temperature_Table[0].TemperatureR;
451 TMP1 = Batt_Temperature_Table[0].BatteryTemp;
452
453 for (i = 0; i <= 16; i++) {
454 if (Res >= Batt_Temperature_Table[i].TemperatureR) {
455 RES2 = Batt_Temperature_Table[i].TemperatureR;
456 TMP2 = Batt_Temperature_Table[i].BatteryTemp;
457 break;
458 } else {
459 RES1 = Batt_Temperature_Table[i].TemperatureR;
460 TMP1 = Batt_Temperature_Table[i].BatteryTemp;
461 }
462 }
463
464 TBatt_Value = (((Res - RES2) * TMP1) + ((RES1 - Res) * TMP2)) / (RES1 - RES2);
465 }
466
467 return TBatt_Value;
468}
469
470kal_int32 fgauge_get_Q_max(kal_int16 temperature)
471{
472 kal_int32 ret_Q_max = 0;
473 kal_int32 low_temperature = 0, high_temperature = 0;
474 kal_int32 low_Q_max = 0, high_Q_max = 0;
475
476 if (temperature <= TEMPERATURE_T1) {
477 low_temperature = (-10);
478 low_Q_max = Q_MAX_NEG_10;
479 high_temperature = TEMPERATURE_T1;
480 high_Q_max = Q_MAX_POS_0;
481
482 if (temperature < low_temperature) {
483 temperature = low_temperature;
484 }
485 } else if (temperature <= TEMPERATURE_T2) {
486 low_temperature = TEMPERATURE_T1;
487 low_Q_max = Q_MAX_POS_0;
488 high_temperature = TEMPERATURE_T2;
489 high_Q_max = Q_MAX_POS_25;
490
491 if (temperature < low_temperature) {
492 temperature = low_temperature;
493 }
494 } else {
495 low_temperature = TEMPERATURE_T2;
496 low_Q_max = Q_MAX_POS_25;
497 high_temperature = TEMPERATURE_T3;
498 high_Q_max = Q_MAX_POS_50;
499
500 if (temperature > high_temperature) {
501 temperature = high_temperature;
502 }
503 }
504
505 ret_Q_max = low_Q_max + (((temperature - low_temperature) * (high_Q_max - low_Q_max)
506 ) / (high_temperature - low_temperature)
507 );
508
509 bm_print(BM_LOG_FULL, "[fgauge_get_Q_max] Q_max = %d\r\n", ret_Q_max);
510
511 return ret_Q_max;
512}
513
514
515kal_int32 fgauge_get_Q_max_high_current(kal_int16 temperature)
516{
517 kal_int32 ret_Q_max = 0;
518 kal_int32 low_temperature = 0, high_temperature = 0;
519 kal_int32 low_Q_max = 0, high_Q_max = 0;
520
521 if (temperature <= TEMPERATURE_T1) {
522 low_temperature = (-10);
523 low_Q_max = Q_MAX_NEG_10_H_CURRENT;
524 high_temperature = TEMPERATURE_T1;
525 high_Q_max = Q_MAX_POS_0_H_CURRENT;
526
527 if (temperature < low_temperature) {
528 temperature = low_temperature;
529 }
530 } else if (temperature <= TEMPERATURE_T2) {
531 low_temperature = TEMPERATURE_T1;
532 low_Q_max = Q_MAX_POS_0_H_CURRENT;
533 high_temperature = TEMPERATURE_T2;
534 high_Q_max = Q_MAX_POS_25_H_CURRENT;
535
536 if (temperature < low_temperature) {
537 temperature = low_temperature;
538 }
539 } else {
540 low_temperature = TEMPERATURE_T2;
541 low_Q_max = Q_MAX_POS_25_H_CURRENT;
542 high_temperature = TEMPERATURE_T3;
543 high_Q_max = Q_MAX_POS_50_H_CURRENT;
544
545 if (temperature > high_temperature) {
546 temperature = high_temperature;
547 }
548 }
549
550 ret_Q_max = low_Q_max + (((temperature - low_temperature) * (high_Q_max - low_Q_max)
551 ) / (high_temperature - low_temperature)
552 );
553
554 bm_print(BM_LOG_FULL, "[fgauge_get_Q_max_high_current] Q_max = %d\r\n", ret_Q_max);
555
556 return ret_Q_max;
557}
558
559#endif
560
561int BattVoltToTemp(int dwVolt)
562{
563 kal_int64 TRes_temp;
564 kal_int64 TRes;
565 int sBaTTMP = -100;
566
567 /* TRes_temp = ((kal_int64)RBAT_PULL_UP_R*(kal_int64)dwVolt) / (RBAT_PULL_UP_VOLT-dwVolt); */
568 /* TRes = (TRes_temp * (kal_int64)RBAT_PULL_DOWN_R)/((kal_int64)RBAT_PULL_DOWN_R - TRes_temp); */
569
570 TRes_temp = (RBAT_PULL_UP_R * (kal_int64) dwVolt);
571 do_div(TRes_temp, (RBAT_PULL_UP_VOLT - dwVolt));
572
573#ifdef RBAT_PULL_DOWN_R
574 TRes = (TRes_temp * RBAT_PULL_DOWN_R);
575 do_div(TRes, abs(RBAT_PULL_DOWN_R - TRes_temp));
576#else
577 TRes = TRes_temp;
578#endif
579
580 /* convert register to temperature */
581 sBaTTMP = BattThermistorConverTemp((int)TRes);
582
583 return sBaTTMP;
584}
585
586int force_get_tbat(kal_bool update)
587{
588#if defined(CONFIG_POWER_EXT) || defined(FIXED_TBAT_25)
589 bm_print(BM_LOG_CRTI, "[force_get_tbat] fixed TBAT=25 t\n");
590 return 25;
591#else
592 int bat_temperature_volt = 0;
593 int bat_temperature_val = 0;
594 static int pre_bat_temperature_val = -1;
595 int fg_r_value = 0;
596 kal_int32 fg_current_temp = 0;
597 kal_bool fg_current_state = KAL_FALSE;
598 int bat_temperature_volt_temp = 0;
599 int ret = 0;
600
601 if (update == KAL_TRUE || pre_bat_temperature_val == -1) {
602 /* Get V_BAT_Temperature */
603 bat_temperature_volt = 2;
604 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_TEMP, &bat_temperature_volt);
605
606 if (bat_temperature_volt != 0) {
607#if defined(SOC_BY_HW_FG)
608 fg_r_value = get_r_fg_value();
609
610 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &fg_current_temp);
611 ret =
612 battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN, &fg_current_state);
613 fg_current_temp = fg_current_temp / 10;
614
615 if (fg_current_state == KAL_TRUE) {
616 bat_temperature_volt_temp = bat_temperature_volt;
617 bat_temperature_volt =
618 bat_temperature_volt - ((fg_current_temp * fg_r_value) / 1000);
619 } else {
620 bat_temperature_volt_temp = bat_temperature_volt;
621 bat_temperature_volt =
622 bat_temperature_volt + ((fg_current_temp * fg_r_value) / 1000);
623 }
624#endif
625
626 bat_temperature_val = BattVoltToTemp(bat_temperature_volt);
627 }
628
629 bm_print(BM_LOG_CRTI, "[force_get_tbat] %d,%d,%d,%d,%d,%d\n",
630 bat_temperature_volt_temp, bat_temperature_volt, fg_current_state, fg_current_temp,
631 fg_r_value, bat_temperature_val);
632 pre_bat_temperature_val = bat_temperature_val;
633 } else {
634 bat_temperature_val = pre_bat_temperature_val;
635 }
636 return bat_temperature_val;
637#endif
638}
639EXPORT_SYMBOL(force_get_tbat);
640
641#ifdef MTK_MULTI_BAT_PROFILE_SUPPORT
642int fgauge_get_saddles(void)
643{
644 return sizeof(battery_profile_temperature) / sizeof(BATTERY_PROFILE_STRUC);
645}
646
647int fgauge_get_saddles_r_table(void)
648{
649 return sizeof(r_profile_temperature) / sizeof(R_PROFILE_STRUC);
650}
651
652BATTERY_PROFILE_STRUC_P fgauge_get_profile(kal_uint32 temperature)
653{
654 switch (temperature) {
655 case TEMPERATURE_T0:
656 return &battery_profile_t0[g_fg_battery_id][0];
657 break;
658 case TEMPERATURE_T1:
659 return &battery_profile_t1[g_fg_battery_id][0];
660 break;
661 case TEMPERATURE_T2:
662 return &battery_profile_t2[g_fg_battery_id][0];
663 break;
664 case TEMPERATURE_T3:
665 return &battery_profile_t3[g_fg_battery_id][0];
666 break;
667 case TEMPERATURE_T:
668 return &battery_profile_temperature[0];
669 break;
670 default:
671 return NULL;
672 break;
673 }
674}
675
676R_PROFILE_STRUC_P fgauge_get_profile_r_table(kal_uint32 temperature)
677{
678 switch (temperature) {
679 case TEMPERATURE_T0:
680 return &r_profile_t0[g_fg_battery_id][0];
681 break;
682 case TEMPERATURE_T1:
683 return &r_profile_t1[g_fg_battery_id][0];
684 break;
685 case TEMPERATURE_T2:
686 return &r_profile_t2[g_fg_battery_id][0];
687 break;
688 case TEMPERATURE_T3:
689 return &r_profile_t3[g_fg_battery_id][0];
690 break;
691 case TEMPERATURE_T:
692 return &r_profile_temperature[0];
693 break;
694 default:
695 return NULL;
696 break;
697 }
698}
699#else
700int fgauge_get_saddles(void)
701{
702 return sizeof(battery_profile_t2) / sizeof(BATTERY_PROFILE_STRUC);
703}
704
705int fgauge_get_saddles_r_table(void)
706{
707 return sizeof(r_profile_t2) / sizeof(R_PROFILE_STRUC);
708}
709
710BATTERY_PROFILE_STRUC_P fgauge_get_profile(kal_uint32 temperature)
711{
712 switch (temperature) {
713 case TEMPERATURE_T0:
714 return &battery_profile_t0[0];
715 break;
716 case TEMPERATURE_T1:
717 return &battery_profile_t1[0];
718 break;
719 case TEMPERATURE_T2:
720 return &battery_profile_t2[0];
721 break;
722 case TEMPERATURE_T3:
723 return &battery_profile_t3[0];
724 break;
725 case TEMPERATURE_T:
726 return &battery_profile_temperature[0];
727 break;
728 default:
729 return NULL;
730 break;
731 }
732}
733
734R_PROFILE_STRUC_P fgauge_get_profile_r_table(kal_uint32 temperature)
735{
736 switch (temperature) {
737 case TEMPERATURE_T0:
738 return &r_profile_t0[0];
739 break;
740 case TEMPERATURE_T1:
741 return &r_profile_t1[0];
742 break;
743 case TEMPERATURE_T2:
744 return &r_profile_t2[0];
745 break;
746 case TEMPERATURE_T3:
747 return &r_profile_t3[0];
748 break;
749 case TEMPERATURE_T:
750 return &r_profile_temperature[0];
751 break;
752 default:
753 return NULL;
754 break;
755 }
756}
757#endif
758
759kal_int32 fgauge_read_capacity_by_v(kal_int32 voltage)
760{
761 int i = 0, saddles = 0;
762 BATTERY_PROFILE_STRUC_P profile_p;
763 kal_int32 ret_percent = 0;
764
765 profile_p = fgauge_get_profile(TEMPERATURE_T);
766 if (profile_p == NULL) {
767 bm_print(BM_LOG_CRTI, "[FGADC] fgauge get ZCV profile : fail !\r\n");
768 return 100;
769 }
770
771 saddles = fgauge_get_saddles();
772
773 if (voltage > (profile_p + 0)->voltage) {
774 return 100; /* battery capacity, not dod */
775 }
776 if (voltage < (profile_p + saddles - 1)->voltage) {
777 return 0; /* battery capacity, not dod */
778 }
779
780 for (i = 0; i < saddles - 1; i++) {
781 if ((voltage <= (profile_p + i)->voltage)
782 && (voltage >= (profile_p + i + 1)->voltage)) {
783 ret_percent =
784 (profile_p + i)->percentage +
785 (((((profile_p + i)->voltage) -
786 voltage) * (((profile_p + i + 1)->percentage) -
787 ((profile_p + i)->percentage))
788 ) / (((profile_p + i)->voltage) - ((profile_p + i + 1)->voltage))
789 );
790
791 break;
792 }
793
794 }
795 ret_percent = 100 - ret_percent;
796
797 return ret_percent;
798}
799
800kal_int32 fgauge_read_v_by_capacity(int bat_capacity)
801{
802 int i = 0, saddles = 0;
803 BATTERY_PROFILE_STRUC_P profile_p;
804 kal_int32 ret_volt = 0;
805
806 profile_p = fgauge_get_profile(TEMPERATURE_T);
807 if (profile_p == NULL) {
808 bm_print(BM_LOG_CRTI,
809 "[fgauge_read_v_by_capacity] fgauge get ZCV profile : fail !\r\n");
810 return 3700;
811 }
812
813 saddles = fgauge_get_saddles();
814
815 if (bat_capacity < (profile_p + 0)->percentage) {
816 return 3700;
817 }
818 if (bat_capacity > (profile_p + saddles - 1)->percentage) {
819 return 3700;
820 }
821
822 for (i = 0; i < saddles - 1; i++) {
823 if ((bat_capacity >= (profile_p + i)->percentage)
824 && (bat_capacity <= (profile_p + i + 1)->percentage)) {
825 ret_volt =
826 (profile_p + i)->voltage -
827 (((bat_capacity -
828 ((profile_p + i)->percentage)) * (((profile_p + i)->voltage) -
829 ((profile_p + i + 1)->voltage))
830 ) / (((profile_p + i + 1)->percentage) - ((profile_p + i)->percentage))
831 );
832
833 break;
834 }
835 }
836
837 return ret_volt;
838}
839
840kal_int32 fgauge_read_d_by_v(kal_int32 volt_bat)
841{
842 int i = 0, saddles = 0;
843 BATTERY_PROFILE_STRUC_P profile_p;
844 kal_int32 ret_d = 0;
845
846 profile_p = fgauge_get_profile(TEMPERATURE_T);
847 if (profile_p == NULL) {
848 bm_print(BM_LOG_CRTI, "[FGADC] fgauge get ZCV profile : fail !\r\n");
849 return 100;
850 }
851
852 saddles = fgauge_get_saddles();
853
854 if (volt_bat > (profile_p + 0)->voltage) {
855 return 0;
856 }
857 if (volt_bat < (profile_p + saddles - 1)->voltage) {
858 return 100;
859 }
860
861 for (i = 0; i < saddles - 1; i++) {
862 if ((volt_bat <= (profile_p + i)->voltage)
863 && (volt_bat >= (profile_p + i + 1)->voltage)) {
864 ret_d =
865 (profile_p + i)->percentage +
866 (((((profile_p + i)->voltage) -
867 volt_bat) * (((profile_p + i + 1)->percentage) -
868 ((profile_p + i)->percentage))
869 ) / (((profile_p + i)->voltage) - ((profile_p + i + 1)->voltage))
870 );
871
872 break;
873 }
874
875 }
876
877 return ret_d;
878}
879
880kal_int32 fgauge_read_v_by_d(int d_val)
881{
882 int i = 0, saddles = 0;
883 BATTERY_PROFILE_STRUC_P profile_p;
884 kal_int32 ret_volt = 0;
885
886 profile_p = fgauge_get_profile(TEMPERATURE_T);
887 if (profile_p == NULL) {
888 bm_print(BM_LOG_CRTI,
889 "[fgauge_read_v_by_capacity] fgauge get ZCV profile : fail !\r\n");
890 return 3700;
891 }
892
893 saddles = fgauge_get_saddles();
894
895 if (d_val < (profile_p + 0)->percentage) {
896 return 3700;
897 }
898 if (d_val > (profile_p + saddles - 1)->percentage) {
899 return 3700;
900 }
901
902 for (i = 0; i < saddles - 1; i++) {
903 if ((d_val >= (profile_p + i)->percentage)
904 && (d_val <= (profile_p + i + 1)->percentage)) {
905 ret_volt =
906 (profile_p + i)->voltage -
907 (((d_val -
908 ((profile_p + i)->percentage)) * (((profile_p + i)->voltage) -
909 ((profile_p + i + 1)->voltage))
910 ) / (((profile_p + i + 1)->percentage) - ((profile_p + i)->percentage))
911 );
912
913 break;
914 }
915 }
916
917 return ret_volt;
918}
919
920kal_int32 fgauge_read_r_bat_by_v(kal_int32 voltage)
921{
922 int i = 0, saddles = 0;
923 R_PROFILE_STRUC_P profile_p;
924 kal_int32 ret_r = 0;
925
926 profile_p = fgauge_get_profile_r_table(TEMPERATURE_T);
927 if (profile_p == NULL) {
928 bm_print(BM_LOG_CRTI, "[FGADC] fgauge get R-Table profile : fail !\r\n");
929 return (profile_p + 0)->resistance;
930 }
931
932 saddles = fgauge_get_saddles_r_table();
933
934 if (voltage > (profile_p + 0)->voltage) {
935 return (profile_p + 0)->resistance;
936 }
937 if (voltage < (profile_p + saddles - 1)->voltage) {
938 return (profile_p + saddles - 1)->resistance;
939 }
940
941 for (i = 0; i < saddles - 1; i++) {
942 if ((voltage <= (profile_p + i)->voltage)
943 && (voltage >= (profile_p + i + 1)->voltage)) {
944 ret_r =
945 (profile_p + i)->resistance +
946 (((((profile_p + i)->voltage) -
947 voltage) * (((profile_p + i + 1)->resistance) -
948 ((profile_p + i)->resistance))
949 ) / (((profile_p + i)->voltage) - ((profile_p + i + 1)->voltage))
950 );
951 break;
952 }
953 }
954
955 return ret_r;
956}
957
958void fgauge_construct_battery_profile_init(void)
959{
960 BATTERY_PROFILE_STRUC_P temp_profile_p, profile_p[PROFILE_SIZE];
961 int i, j, saddles, profile_index;
962 kal_int32 low_p = 0, high_p = 0, now_p = 0, low_vol = 0, high_vol = 0;
963
964 profile_p[0] = fgauge_get_profile(TEMPERATURE_T0);
965 profile_p[1] = fgauge_get_profile(TEMPERATURE_T1);
966 profile_p[2] = fgauge_get_profile(TEMPERATURE_T2);
967 profile_p[3] = fgauge_get_profile(TEMPERATURE_T3);
968 saddles = fgauge_get_saddles();
969 temp_profile_p = (BATTERY_PROFILE_STRUC_P) kmalloc(51 * sizeof(*temp_profile_p), GFP_KERNEL);
970 memset(temp_profile_p, 0, 51 * sizeof(*temp_profile_p));
971 for (i=0; i< PROFILE_SIZE; i++) {
972 profile_index = 0;
973 for (j=0; j*2 <= 100; j++) {
974 while (profile_index < saddles && profile_index >=0) {
975 if (((profile_p[i] + profile_index)->percentage) < j*2) {
976 profile_index ++;
977 continue;
978 } else if (((profile_p[i] + profile_index)->percentage) == j*2) {
979 (temp_profile_p + j)->voltage = (profile_p[i] + profile_index)->voltage;
980 (temp_profile_p + j)->percentage = (profile_p[i] + profile_index)->percentage;
981 break;
982 }
983 low_p = (profile_p[i]+profile_index-1)->percentage;
984 high_p = (profile_p[i]+profile_index)->percentage;
985 now_p = j*2;
986 low_vol = (profile_p[i]+profile_index)->voltage;
987 high_vol = (profile_p[i]+profile_index-1)-> voltage;
988 (temp_profile_p + j)->voltage = (low_vol*1000 + ((high_vol - low_vol) * 1000 * (now_p - low_p) / (high_p - low_p))) / 1000;
989 (temp_profile_p + j)->percentage = j*2;
990
991 break;
992 }
993 bm_print(BM_LOG_CRTI, "new battery_profile[%d,%d] <%d,%d>\n", i, j, (temp_profile_p + j)->percentage, (temp_profile_p + j)->voltage);
994 }
995 profile_p[i] = temp_profile_p;
996 }
997 kfree(temp_profile_p);
998}
999
1000void fgauge_construct_battery_profile(kal_int32 temperature, BATTERY_PROFILE_STRUC_P temp_profile_p)
1001{
1002 BATTERY_PROFILE_STRUC_P low_profile_p, high_profile_p;
1003 kal_int32 low_temperature, high_temperature;
1004 int i, saddles;
1005 kal_int32 temp_v_1 = 0, temp_v_2 = 0;
1006
1007 if (temperature <= TEMPERATURE_T1) {
1008 low_profile_p = fgauge_get_profile(TEMPERATURE_T0);
1009 high_profile_p = fgauge_get_profile(TEMPERATURE_T1);
1010 low_temperature = (-10);
1011 high_temperature = TEMPERATURE_T1;
1012
1013 if (temperature < low_temperature) {
1014 temperature = low_temperature;
1015 }
1016 } else if (temperature <= TEMPERATURE_T2) {
1017 low_profile_p = fgauge_get_profile(TEMPERATURE_T1);
1018 high_profile_p = fgauge_get_profile(TEMPERATURE_T2);
1019 low_temperature = TEMPERATURE_T1;
1020 high_temperature = TEMPERATURE_T2;
1021
1022 if (temperature < low_temperature) {
1023 temperature = low_temperature;
1024 }
1025 } else {
1026 low_profile_p = fgauge_get_profile(TEMPERATURE_T2);
1027 high_profile_p = fgauge_get_profile(TEMPERATURE_T3);
1028 low_temperature = TEMPERATURE_T2;
1029 high_temperature = TEMPERATURE_T3;
1030
1031 if (temperature > high_temperature) {
1032 temperature = high_temperature;
1033 }
1034 }
1035
1036 saddles = fgauge_get_saddles();
1037
1038 for (i = 0; i < saddles; i++) {
1039 if (((high_profile_p + i)->voltage) > ((low_profile_p + i)->voltage)) {
1040 temp_v_1 = (high_profile_p + i)->voltage;
1041 temp_v_2 = (low_profile_p + i)->voltage;
1042
1043 (temp_profile_p + i)->voltage = temp_v_2 +
1044 (((temperature - low_temperature) * (temp_v_1 - temp_v_2)
1045 ) / (high_temperature - low_temperature)
1046 );
1047 } else {
1048 temp_v_1 = (low_profile_p + i)->voltage;
1049 temp_v_2 = (high_profile_p + i)->voltage;
1050
1051 (temp_profile_p + i)->voltage = temp_v_2 +
1052 (((high_temperature - temperature) * (temp_v_1 - temp_v_2)
1053 ) / (high_temperature - low_temperature)
1054 );
1055 }
1056
1057 (temp_profile_p + i)->percentage = (high_profile_p + i)->percentage;
1058#if 0
1059 (temp_profile_p + i)->voltage = temp_v_2 +
1060 (((temperature - low_temperature) * (temp_v_1 - temp_v_2)
1061 ) / (high_temperature - low_temperature)
1062 );
1063#endif
1064 }
1065
1066
1067 /* Dumpt new battery profile */
1068 for (i = 0; i < saddles; i++) {
1069 bm_print(BM_LOG_CRTI, "<DOD,Voltage> at %d = <%d,%d>\r\n",
1070 temperature, (temp_profile_p + i)->percentage,
1071 (temp_profile_p + i)->voltage);
1072 }
1073
1074}
1075
1076void fgauge_construct_r_table_profile(kal_int32 temperature, R_PROFILE_STRUC_P temp_profile_p)
1077{
1078 R_PROFILE_STRUC_P low_profile_p, high_profile_p;
1079 kal_int32 low_temperature, high_temperature;
1080 int i, saddles;
1081 kal_int32 temp_v_1 = 0, temp_v_2 = 0;
1082 kal_int32 temp_r_1 = 0, temp_r_2 = 0;
1083
1084 if (temperature <= TEMPERATURE_T1) {
1085 low_profile_p = fgauge_get_profile_r_table(TEMPERATURE_T0);
1086 high_profile_p = fgauge_get_profile_r_table(TEMPERATURE_T1);
1087 low_temperature = (-10);
1088 high_temperature = TEMPERATURE_T1;
1089
1090 if (temperature < low_temperature) {
1091 temperature = low_temperature;
1092 }
1093 } else if (temperature <= TEMPERATURE_T2) {
1094 low_profile_p = fgauge_get_profile_r_table(TEMPERATURE_T1);
1095 high_profile_p = fgauge_get_profile_r_table(TEMPERATURE_T2);
1096 low_temperature = TEMPERATURE_T1;
1097 high_temperature = TEMPERATURE_T2;
1098
1099 if (temperature < low_temperature) {
1100 temperature = low_temperature;
1101 }
1102 } else {
1103 low_profile_p = fgauge_get_profile_r_table(TEMPERATURE_T2);
1104 high_profile_p = fgauge_get_profile_r_table(TEMPERATURE_T3);
1105 low_temperature = TEMPERATURE_T2;
1106 high_temperature = TEMPERATURE_T3;
1107
1108 if (temperature > high_temperature) {
1109 temperature = high_temperature;
1110 }
1111 }
1112
1113 saddles = fgauge_get_saddles_r_table();
1114
1115 /* Interpolation for V_BAT */
1116 for (i = 0; i < saddles; i++) {
1117 if (((high_profile_p + i)->voltage) > ((low_profile_p + i)->voltage)) {
1118 temp_v_1 = (high_profile_p + i)->voltage;
1119 temp_v_2 = (low_profile_p + i)->voltage;
1120
1121 (temp_profile_p + i)->voltage = temp_v_2 +
1122 (((temperature - low_temperature) * (temp_v_1 - temp_v_2)
1123 ) / (high_temperature - low_temperature)
1124 );
1125 } else {
1126 temp_v_1 = (low_profile_p + i)->voltage;
1127 temp_v_2 = (high_profile_p + i)->voltage;
1128
1129 (temp_profile_p + i)->voltage = temp_v_2 +
1130 (((high_temperature - temperature) * (temp_v_1 - temp_v_2)
1131 ) / (high_temperature - low_temperature)
1132 );
1133 }
1134
1135#if 0
1136 /* (temp_profile_p + i)->resistance = (high_profile_p + i)->resistance; */
1137
1138 (temp_profile_p + i)->voltage = temp_v_2 +
1139 (((temperature - low_temperature) * (temp_v_1 - temp_v_2)
1140 ) / (high_temperature - low_temperature)
1141 );
1142#endif
1143 }
1144
1145 /* Interpolation for R_BAT */
1146 for (i = 0; i < saddles; i++) {
1147 if (((high_profile_p + i)->resistance) > ((low_profile_p + i)->resistance)) {
1148 temp_r_1 = (high_profile_p + i)->resistance;
1149 temp_r_2 = (low_profile_p + i)->resistance;
1150
1151 (temp_profile_p + i)->resistance = temp_r_2 +
1152 (((temperature - low_temperature) * (temp_r_1 - temp_r_2)
1153 ) / (high_temperature - low_temperature)
1154 );
1155 } else {
1156 temp_r_1 = (low_profile_p + i)->resistance;
1157 temp_r_2 = (high_profile_p + i)->resistance;
1158
1159 (temp_profile_p + i)->resistance = temp_r_2 +
1160 (((high_temperature - temperature) * (temp_r_1 - temp_r_2)
1161 ) / (high_temperature - low_temperature)
1162 );
1163 }
1164
1165#if 0
1166 /* (temp_profile_p + i)->voltage = (high_profile_p + i)->voltage; */
1167
1168 (temp_profile_p + i)->resistance = temp_r_2 +
1169 (((temperature - low_temperature) * (temp_r_1 - temp_r_2)
1170 ) / (high_temperature - low_temperature)
1171 );
1172#endif
1173 }
1174
1175 /* Dumpt new r-table profile */
1176 for (i = 0; i < saddles; i++) {
1177 bm_print(BM_LOG_CRTI, "<Rbat,VBAT> at %d = <%d,%d>\r\n",
1178 temperature, (temp_profile_p + i)->resistance,
1179 (temp_profile_p + i)->voltage);
1180 }
1181
1182}
1183
1184void fgauge_construct_table_by_temp(void)
1185{
1186#if defined(CONFIG_POWER_EXT)
1187#else
1188 kal_uint32 i;
1189 static kal_int32 init_temp = KAL_TRUE;
1190 static kal_int32 curr_temp, last_temp, avg_temp;
1191 static kal_int32 battTempBuffer[TEMP_AVERAGE_SIZE];
1192 static kal_int32 temperature_sum;
1193 static kal_uint8 tempIndex;
1194
1195 curr_temp = battery_meter_get_battery_temperature();
1196
1197 /* Temperature window init */
1198 if (init_temp == KAL_TRUE) {
1199 for (i = 0; i < TEMP_AVERAGE_SIZE; i++) {
1200 battTempBuffer[i] = curr_temp;
1201 }
1202 last_temp = curr_temp;
1203 temperature_sum = curr_temp * TEMP_AVERAGE_SIZE;
1204 init_temp = KAL_FALSE;
1205 }
1206 /* Temperature sliding window */
1207 temperature_sum -= battTempBuffer[tempIndex];
1208 temperature_sum += curr_temp;
1209 battTempBuffer[tempIndex] = curr_temp;
1210 avg_temp = (temperature_sum) / TEMP_AVERAGE_SIZE;
1211
1212 if (avg_temp != last_temp) {
1213 bm_print(BM_LOG_FULL,
1214 "[fgauge_construct_table_by_temp] reconstruct table by temperature change from (%d) to (%d)\r\n",
1215 last_temp, avg_temp);
1216 fgauge_construct_r_table_profile(curr_temp,
1217 fgauge_get_profile_r_table(TEMPERATURE_T));
1218 fgauge_construct_battery_profile(curr_temp, fgauge_get_profile(TEMPERATURE_T));
1219 last_temp = avg_temp;
1220 temperature_change = 1;
1221 }
1222
1223 tempIndex = (tempIndex + 1) % TEMP_AVERAGE_SIZE;
1224
1225#endif
1226}
1227
1228#ifdef CUST_CAPACITY_OCV2CV_TRANSFORM
1229void fgauge_get_current_factor(void)
1230{
1231#if defined(CONFIG_POWER_EXT)
1232#else
1233 kal_uint32 i;
1234 static kal_int32 init_current = KAL_TRUE;
1235
1236 static kal_int32 inst_current, avg_current;
1237 static kal_int32 battCurrentBuffer[TEMP_AVERAGE_SIZE];
1238 static kal_int32 current_sum;
1239
1240 static kal_uint8 tempcurrentIndex = 0;
1241
1242 if(KAL_TRUE == gFG_Is_Charging)
1243 {
1244 init_current = KAL_TRUE;
1245 g_currentfactor = 100;
1246
1247 bm_print(BM_LOG_CRTI, "[fgauge_get_current_factor] Charging!!\r\n");
1248 return;
1249 }
1250
1251 inst_current = oam_i_2;
1252
1253 // Current window init
1254 if (init_current == KAL_TRUE)
1255 {
1256 for (i=0; i<TEMP_AVERAGE_SIZE; i++)
1257 {
1258 battCurrentBuffer[i] = inst_current;
1259 }
1260 current_sum = inst_current * TEMP_AVERAGE_SIZE;
1261
1262 init_current = KAL_FALSE;
1263 }
1264
1265 // Current sliding window
1266 current_sum -= battCurrentBuffer[tempcurrentIndex];
1267 current_sum += inst_current;
1268 battCurrentBuffer[tempcurrentIndex] = inst_current;
1269 avg_current = (current_sum)/TEMP_AVERAGE_SIZE;
1270
1271 g_currentfactor = avg_current *100/ 6000; //calculate factor by 600ma
1272
1273 bm_print(BM_LOG_CRTI, "[fgauge_get_current_factor] %d,%d,%d,%d\r\n",
1274 inst_current, avg_current, g_currentfactor, gFG_Is_Charging);
1275
1276 tempcurrentIndex = (tempcurrentIndex+1)%TEMP_AVERAGE_SIZE;
1277#endif
1278}
1279
1280kal_int32 fgauge_get_Q_max_high_current_by_current(kal_int16 i_current, kal_int16 val_temp)
1281{
1282 kal_int32 ret_Q_max=0;
1283 int iIndex = 0, saddles = 0;
1284 kal_int32 OCV_temp = 0, Rbat_temp = 0, V_drop = 0;
1285
1286 //for Qmax initializing
1287 ret_Q_max = fgauge_get_Q_max_high_current(val_temp);
1288
1289 //get Rbat and OCV table of the current temperature
1290 R_PROFILE_STRUC_P p_profile_r = fgauge_get_profile_r_table(TEMPERATURE_T);
1291 BATTERY_PROFILE_STRUC_P p_profile_battery = fgauge_get_profile(TEMPERATURE_T);
1292 if (p_profile_r == NULL || p_profile_battery == NULL)
1293 {
1294 bm_print(BM_LOG_CRTI, "[fgauge_get_Q_max_by_current] get R-Table profile/OCV table profile : fail !\r\n");
1295 return ret_Q_max;
1296 }
1297
1298 if ( 0 == p_profile_r->resistance || 0 == p_profile_battery->voltage)
1299 {
1300 bm_print(BM_LOG_CRTI, "[fgauge_get_Q_max_by_current] R-Table profile/OCV table profile : not ready !\r\n");
1301 return ret_Q_max;
1302 }
1303
1304 saddles = fgauge_get_saddles();
1305
1306 //get Qmax in current temperature(>3.4)
1307 for (iIndex = 0; iIndex < saddles - 1; iIndex++)
1308 {
1309 OCV_temp = (p_profile_battery+iIndex)->voltage;
1310 Rbat_temp = (p_profile_r+iIndex)->resistance;
1311 V_drop = (i_current * Rbat_temp)/10000;
1312
1313 if( V_drop > (OCV_temp - 3400))
1314 {
1315 if (iIndex <= 1)
1316 ret_Q_max = step_of_Qmax;
1317 else
1318 ret_Q_max = (iIndex-1) * step_of_Qmax;
1319 break;
1320 }
1321 }
1322
1323 bm_print(BM_LOG_CRTI, "[fgauge_get_Q_max_by_current] %d,%d,%d,%d,%d\r\n", \
1324 i_current, iIndex, OCV_temp, Rbat_temp, ret_Q_max );
1325
1326 return ret_Q_max;
1327}
1328#endif
1329
1330void fg_qmax_update_for_aging(void)
1331{
1332#if defined(CONFIG_POWER_EXT)
1333#else
1334 kal_bool hw_charging_done = bat_is_charging_full();
1335
1336 if (hw_charging_done == KAL_TRUE) /* charging full, g_HW_Charging_Done == 1 */
1337 {
1338 if (gFG_DOD0 > 85) {
1339 if (gFG_columb < 0)
1340 gFG_columb = gFG_columb - gFG_columb * 2; /* absolute value */
1341
1342 gFG_BATT_CAPACITY_aging =
1343 (((gFG_columb * 1000) + (5 * gFG_DOD0)) / gFG_DOD0) / 10;
1344
1345 /* tuning */
1346 gFG_BATT_CAPACITY_aging =
1347 (gFG_BATT_CAPACITY_aging * 100) / AGING_TUNING_VALUE;
1348
1349 if (gFG_BATT_CAPACITY_aging == 0) {
1350 gFG_BATT_CAPACITY_aging =
1351 fgauge_get_Q_max(battery_meter_get_battery_temperature());
1352 bm_print(BM_LOG_CRTI,
1353 "[fg_qmax_update_for_aging] error, restore gFG_BATT_CAPACITY_aging (%d)\n",
1354 gFG_BATT_CAPACITY_aging);
1355 }
1356
1357 bm_print(BM_LOG_CRTI,
1358 "[fg_qmax_update_for_aging] need update : gFG_columb=%d, gFG_DOD0=%d, new_qmax=%d\r\n",
1359 gFG_columb, gFG_DOD0, gFG_BATT_CAPACITY_aging);
1360 } else {
1361 bm_print(BM_LOG_CRTI,
1362 "[fg_qmax_update_for_aging] no update : gFG_columb=%d, gFG_DOD0=%d, new_qmax=%d\r\n",
1363 gFG_columb, gFG_DOD0, gFG_BATT_CAPACITY_aging);
1364 }
1365 } else {
1366 bm_print(BM_LOG_CRTI, "[fg_qmax_update_for_aging] hw_charging_done=%d\r\n",
1367 hw_charging_done);
1368 }
1369#endif
1370}
1371
1372
1373void dod_init(void)
1374{
1375#if defined(SOC_BY_HW_FG)
1376 int ret = 0;
1377 /* use get_hw_ocv----------------------------------------------------------------- */
1378 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage);
1379 gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage);
1380
1381 bm_print(BM_LOG_CRTI, "[FGADC] get_hw_ocv=%d, HW_SOC=%d, SW_SOC = %d\n",
1382 gFG_voltage, gFG_capacity_by_v, gFG_capacity_by_v_init);
1383#if defined(EXTERNAL_SWCHR_SUPPORT)
1384 /* compare with hw_ocv & sw_ocv, check if less than or equal to 5% tolerance */
1385 if ((abs(gFG_capacity_by_v_init - gFG_capacity_by_v) > 5)
1386 && (bat_is_charger_exist() == KAL_TRUE)) {
1387 gFG_capacity_by_v = gFG_capacity_by_v_init;
1388 }
1389#endif
1390#if defined(HW_FG_FORCE_USE_SW_OCV)
1391 gFG_capacity_by_v = gFG_capacity_by_v_init;
1392 bm_print(BM_LOG_CRTI, "[FGADC] HW_FG_FORCE_USE_SW_OCV : HW_SOC=%d, SW_SOC = %d\n",
1393 gFG_capacity_by_v, gFG_capacity_by_v_init);
1394#endif
1395 /* ------------------------------------------------------------------------------- */
1396#endif
1397
1398#if defined(CONFIG_POWER_EXT)
1399 g_rtc_fg_soc = gFG_capacity_by_v;
1400#else
1401 g_rtc_fg_soc = get_rtc_spare_fg_value();
1402#endif
1403#if defined(SOC_BY_HW_FG)
1404#if defined(INIT_SOC_BY_SW_SOC)
1405 if (((g_rtc_fg_soc != 0)
1406 && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) <= CUST_POWERON_DELTA_CAPACITY_TOLRANCE)
1407 || (abs(gFG_capacity_by_v_init - g_rtc_fg_soc) < abs(gFG_capacity_by_v - gFG_capacity_by_v_init))))
1408 || ((g_rtc_fg_soc != 0)
1409 && (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
1410 || g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
1411 || g_boot_mode == RECOVERY_BOOT)))
1412
1413#else
1414 if (((g_rtc_fg_soc != 0)
1415 && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) < CUST_POWERON_DELTA_CAPACITY_TOLRANCE))
1416 &&
1417 ((gFG_capacity_by_v > CUST_POWERON_LOW_CAPACITY_TOLRANCE
1418 || bat_is_charger_exist() == KAL_TRUE)))
1419 || ((g_rtc_fg_soc != 0)
1420 && (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
1421 || g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
1422 || g_boot_mode == RECOVERY_BOOT)))
1423#endif
1424 {
1425 gFG_capacity_by_v = g_rtc_fg_soc;
1426 }
1427#elif defined(SOC_BY_SW_FG)
1428 if (((g_rtc_fg_soc != 0)
1429 && (((abs(g_rtc_fg_soc - gFG_capacity_by_v)) < CUST_POWERON_DELTA_CAPACITY_TOLRANCE)
1430 || (abs(g_rtc_fg_soc - fgauge_read_capacity_by_v(g_booting_vbat)) < CUST_POWERON_DELTA_CAPACITY_TOLRANCE))
1431 &&
1432 ((gFG_capacity_by_v > CUST_POWERON_LOW_CAPACITY_TOLRANCE
1433 || bat_is_charger_exist() == KAL_TRUE)))
1434 || ((g_rtc_fg_soc != 0)
1435 && (g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT
1436 || g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT
1437 || g_boot_mode == RECOVERY_BOOT)))
1438 {
1439 gFG_capacity_by_v = g_rtc_fg_soc;
1440 }
1441/*************add by zero***********/
1442 else if(((g_rtc_fg_soc != 0) && ((((abs(g_rtc_fg_soc-gFG_capacity_by_v)) < 55) && ((abs(g_rtc_fg_soc-gFG_capacity_by_v)) >= CUST_POWERON_DELTA_CAPACITY_TOLRANCE))||(((abs(g_rtc_fg_soc-g_booting_vbat)) < 55) && ((abs(g_rtc_fg_soc-g_booting_vbat))) >= CUST_POWERON_DELTA_CAPACITY_TOLRANCE))
1443 &&(( gFG_capacity_by_v > CUST_POWERON_LOW_CAPACITY_TOLRANCE || bat_is_charger_exist() == KAL_TRUE)))
1444 || ((g_rtc_fg_soc != 0) &&(g_boot_reason == BR_WDT_BY_PASS_PWK || g_boot_reason == BR_WDT || g_boot_reason == BR_TOOL_BY_PASS_PWK || g_boot_reason == BR_2SEC_REBOOT || g_boot_mode == RECOVERY_BOOT)))
1445
1446 {
1447 gFG_capacity_by_v = (g_rtc_fg_soc + gFG_capacity_by_v) / 2;
1448 printk("gandy-----set gFG_capacity_by_v = (g_rtc_fg_soc + gFG_capacity_by_v) / 2 = g_rtc_fg_soc; ");
1449 }
1450 /**********end********************/
1451#endif
1452 bm_print(BM_LOG_CRTI, "[FGADC] g_rtc_fg_soc=%d, gFG_capacity_by_v=%d\n",
1453 g_rtc_fg_soc, gFG_capacity_by_v);
1454
1455 if (gFG_capacity_by_v == 0 && bat_is_charger_exist() == KAL_TRUE) {
1456 gFG_capacity_by_v = 1;
1457
1458 bm_print(BM_LOG_CRTI, "[FGADC] gFG_capacity_by_v=%d\n", gFG_capacity_by_v);
1459 }
1460 gFG_capacity = gFG_capacity_by_v;
1461 gFG_capacity_by_c_init = gFG_capacity;
1462 gFG_capacity_by_c = gFG_capacity;
1463
1464 gFG_DOD0 = 100 - gFG_capacity;
1465 gFG_DOD1 = gFG_DOD0;
1466
1467 gfg_percent_check_point = gFG_capacity;
1468
1469#if defined(CHANGE_TRACKING_POINT)
1470 gFG_15_vlot = fgauge_read_v_by_capacity((100 - g_tracking_point));
1471 bm_print(BM_LOG_CRTI, "[FGADC] gFG_15_vlot = %dmV\n", gFG_15_vlot);
1472#else
1473 /* gFG_15_vlot = fgauge_read_v_by_capacity(86); //14% */
1474 gFG_15_vlot = fgauge_read_v_by_capacity((100 - g_tracking_point));
1475 bm_print(BM_LOG_CRTI, "[FGADC] gFG_15_vlot = %dmV\n", gFG_15_vlot);
1476 if ((gFG_15_vlot > 3800) || (gFG_15_vlot < 3600)) {
1477 bm_print(BM_LOG_CRTI, "[FGADC] gFG_15_vlot(%d) over range, reset to 3700\n",
1478 gFG_15_vlot);
1479 gFG_15_vlot = 3700;
1480 }
1481#endif
1482}
1483
1484/* ============================================================ // SW FG */
1485kal_int32 mtk_imp_tracking(kal_int32 ori_voltage, kal_int32 ori_current, kal_int32 recursion_time)
1486{
1487 kal_int32 ret_compensate_value = 0;
1488 kal_int32 temp_voltage_1 = ori_voltage;
1489 kal_int32 temp_voltage_2 = temp_voltage_1;
1490 int i = 0;
1491
1492 for (i = 0; i < recursion_time; i++) {
1493 gFG_resistance_bat = fgauge_read_r_bat_by_v(temp_voltage_2);
1494 ret_compensate_value = ((ori_current) * (gFG_resistance_bat + R_FG_VALUE)) / 1000;
1495 ret_compensate_value = (ret_compensate_value + (10 / 2)) / 10;
1496 temp_voltage_2 = temp_voltage_1 + ret_compensate_value;
1497
1498 bm_print(BM_LOG_FULL,
1499 "[mtk_imp_tracking] temp_voltage_2=%d,temp_voltage_1=%d,ret_compensate_value=%d,gFG_resistance_bat=%d\n",
1500 temp_voltage_2, temp_voltage_1, ret_compensate_value, gFG_resistance_bat);
1501 }
1502
1503 gFG_resistance_bat = fgauge_read_r_bat_by_v(temp_voltage_2);
1504 ret_compensate_value =
1505 ((ori_current) * (gFG_resistance_bat + R_FG_VALUE + FG_METER_RESISTANCE)) / 1000;
1506 ret_compensate_value = (ret_compensate_value + (10 / 2)) / 10;
1507
1508 gFG_compensate_value = ret_compensate_value;
1509
1510 bm_print(BM_LOG_FULL,
1511 "[mtk_imp_tracking] temp_voltage_2=%d,temp_voltage_1=%d,ret_compensate_value=%d,gFG_resistance_bat=%d\n",
1512 temp_voltage_2, temp_voltage_1, ret_compensate_value, gFG_resistance_bat);
1513
1514 return ret_compensate_value;
1515}
1516
1517void oam_init(void)
1518{
1519 int ret = 0;
1520 kal_int32 vbat_capacity = 0;
1521 kal_bool charging_enable = KAL_FALSE;
1522
1523 /*stop charging for vbat measurement */
1524 battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);
1525
1526 msleep(50);
1527
1528 g_booting_vbat = 5; /* set avg times */
1529 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage);
1530 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &g_booting_vbat);
1531
1532/********add by zero ********************/
1533 printk("zero----in function ====%s\n",__func__);
1534 printk("zero---gFG_voltage=%d,g_booting_vbat = %d\n",gFG_voltage,g_booting_vbat);
1535
4b9e9796
S
1536 if(bat_is_charger_exist() == KAL_TRUE)
1537 {
6fa3eb70
S
1538 #ifdef CONFIG_USB_PLUS_DC
1539 printk("zero---BMT_status.charger_type = %d\n",dc_in_state());
1540 if (dc_in_state() == 0)
1541 {
1542 if(gFG_voltage > 3600 && gFG_voltage < 3700)
1543 gFG_voltage = gFG_voltage - 30;
1544 else if(gFG_voltage >= 3700 && gFG_voltage < 4100)
1545 gFG_voltage = gFG_voltage - 90;
1546 else if(gFG_voltage >= 4100 && gFG_voltage < 4190)
1547 gFG_voltage = gFG_voltage - 30;
1548 }
1549 else
1550 {
1551 if(gFG_voltage > 3600 && gFG_voltage < 3700)
1552 gFG_voltage = gFG_voltage - 15;
1553 else if(gFG_voltage >= 3700 && gFG_voltage < 4100)
1554 gFG_voltage = gFG_voltage - 60;
1555 else if(gFG_voltage >= 4100 && gFG_voltage < 4190)
1556 gFG_voltage = gFG_voltage - 15;
1557 }
1558 #else
1559 if(gFG_voltage > 3650 && gFG_voltage < 3715)
1560 gFG_voltage = gFG_voltage - 30;
1561 else if(gFG_voltage >= 3715&& gFG_voltage < 4100)
1562 gFG_voltage = gFG_voltage - 20;
1563 else if(gFG_voltage >= 4100 && gFG_voltage < 4190)
1564 gFG_voltage = gFG_voltage - 10;
4b9e9796
S
1565 #endif
1566 }
1567 else
1568 {
1569/* [BUGFIX]-Add-BEGIN by TCTSZ.leo.guo, 05/26/2015, Fixed voltage calculate to report soc.*/
1570 printk("Fixed voltage calculate to report soc.");
1571 if(gFG_voltage <= 3500)
1572 gFG_voltage = gFG_voltage - 50;
1573/* [BUGFIX]-Add-END by TCTSZ.leo.guo, 05/26/2015*/
1574 }
1575 printk("zero---gFG_voltage=%d\n",gFG_voltage);
6fa3eb70
S
1576 /************add by zero ************************/
1577 gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage);
1578 vbat_capacity = fgauge_read_capacity_by_v(g_booting_vbat);
1579
1580 if (bat_is_charger_exist() == KAL_TRUE) {
1581 bm_print(BM_LOG_CRTI, "[oam_init_inf] gFG_capacity_by_v=%d, vbat_capacity=%d,\n",
1582 gFG_capacity_by_v, vbat_capacity);
1583
1584 /* to avoid plug in cable without battery, then plug in battery to make hw soc = 100% */
1585 /* if the difference bwtween ZCV and vbat is too large, using vbat instead ZCV */
1586 if (((gFG_capacity_by_v == 100) && (vbat_capacity < CUST_POWERON_MAX_VBAT_TOLRANCE))
1587 || (abs(gFG_capacity_by_v - vbat_capacity) >
1588 CUST_POWERON_DELTA_VBAT_TOLRANCE)) {
1589 bm_print(BM_LOG_CRTI,
1590 "[oam_init] fg_vbat=(%d), vbat=(%d), set fg_vat as vat\n",
1591 gFG_voltage, g_booting_vbat);
1592
1593 gFG_voltage = g_booting_vbat;
1594 gFG_capacity_by_v = vbat_capacity;
1595 }
1596 }
1597
1598 gFG_capacity_by_v_init = gFG_capacity_by_v;
1599
1600 dod_init();
1601
1602 gFG_BATT_CAPACITY_aging = fgauge_get_Q_max(force_get_tbat(KAL_FALSE));
1603
1604 /* oam_v_ocv_1 = gFG_voltage; */
1605 /* oam_v_ocv_2 = gFG_voltage; */
1606
1607
1608 oam_v_ocv_init = fgauge_read_v_by_d(gFG_DOD0);
1609 oam_v_ocv_2 = oam_v_ocv_1 = oam_v_ocv_init;
1610 g_vol_bat_hw_ocv = gFG_voltage;
1611
1612 /* vbat = 5; //set avg times */
1613 /* ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &vbat); */
1614 /* oam_r_1 = fgauge_read_r_bat_by_v(vbat); */
1615 oam_r_1 = fgauge_read_r_bat_by_v(gFG_voltage);
1616 oam_r_2 = oam_r_1;
1617
1618 oam_d0 = gFG_DOD0;
1619 oam_d_5 = oam_d0;
1620 oam_i_ori = gFG_current;
1621 g_d_hw_ocv = oam_d0;
1622
1623 if (oam_init_i == 0) {
1624 bm_print(BM_LOG_CRTI,
1625 "[oam_init] oam_v_ocv_1,oam_v_ocv_2,oam_r_1,oam_r_2,oam_d0,oam_i_ori\n");
1626 oam_init_i = 1;
1627 }
1628
1629 bm_print(BM_LOG_CRTI, "[oam_init] %d,%d,%d,%d,%d,%d\n",
1630 oam_v_ocv_1, oam_v_ocv_2, oam_r_1, oam_r_2, oam_d0, oam_i_ori);
1631
1632 bm_print(BM_LOG_CRTI, "[oam_init_inf] hw_OCV, hw_D0, RTC, D0, oam_OCV_init, tbat\n");
1633 bm_print(BM_LOG_CRTI,
1634 "[oam_run_inf] oam_OCV1, oam_OCV2, vbat, I1, I2, R1, R2, Car1, Car2,qmax, tbat\n");
1635 bm_print(BM_LOG_CRTI, "[oam_result_inf] D1, D2, D3, D4, D5, UI_SOC\n");
1636
1637
1638 bm_print(BM_LOG_CRTI, "[oam_init_inf] %d, %d, %d, %d, %d, %d\n",
1639 gFG_voltage, (100 - fgauge_read_capacity_by_v(gFG_voltage)), g_rtc_fg_soc,
1640 gFG_DOD0, oam_v_ocv_init, force_get_tbat(KAL_FALSE));
1641
1642}
1643
1644
1645void oam_run(void)
1646{
1647 int vol_bat = 0;
1648 /* int vol_bat_hw_ocv=0; */
1649 /* int d_hw_ocv=0; */
1650 int charging_current = 0;
1651 int ret = 0;
1652
1653#ifdef CUST_CAPACITY_OCV2CV_TRANSFORM
1654 // Reconstruct table if temp changed;
1655 fgauge_construct_table_by_temp();
1656
1657 // Get current factor
1658 fgauge_get_current_factor();
1659#endif
1660
1661 /* kal_uint32 now_time; */
1662 struct timespec now_time;
1663 kal_int32 delta_time = 0;
1664
1665 /* now_time = rtc_read_hw_time(); */
1666 getrawmonotonic(&now_time);
1667
1668 /* delta_time = now_time - last_oam_run_time; */
1669 delta_time = now_time.tv_sec - last_oam_run_time.tv_sec;
1670
1671 bm_print(BM_LOG_CRTI, "[oam_run_time] delta time=%d\n", delta_time);
1672
1673 last_oam_run_time = now_time;
1674
1675 /* Reconstruct table if temp changed; */
1676 fgauge_construct_table_by_temp();
1677
1678 vol_bat = 15; /* set avg times */
1679 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &vol_bat);
1680
1681 /* ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &vol_bat_hw_ocv); */
1682 /* d_hw_ocv = fgauge_read_d_by_v(vol_bat_hw_ocv); */
1683
1684 oam_i_1 = (((oam_v_ocv_1 - vol_bat) * 1000) * 10) / oam_r_1; /* 0.1mA */
1685 oam_i_2 = (((oam_v_ocv_2 - vol_bat) * 1000) * 10) / oam_r_2; /* 0.1mA */
1686
1687 oam_car_1 = (oam_i_1 * delta_time / 3600) + oam_car_1; /* 0.1mAh */
1688 oam_car_2 = (oam_i_2 * delta_time / 3600) + oam_car_2; /* 0.1mAh */
1689
1690 oam_d_1 = oam_d0 + (oam_car_1 * 100 / 10) / gFG_BATT_CAPACITY_aging;
1691 if (oam_d_1 < 0)
1692 oam_d_1 = 0;
1693 if (oam_d_1 > 100)
1694 oam_d_1 = 100;
1695
1696 oam_d_2 = oam_d0 + (oam_car_2 * 100 / 10) / gFG_BATT_CAPACITY_aging;
1697 if (oam_d_2 < 0)
1698 oam_d_2 = 0;
1699 if (oam_d_2 > 100)
1700 oam_d_2 = 100;
1701
1702 oam_v_ocv_1 = vol_bat + mtk_imp_tracking(vol_bat, oam_i_2, 5);
1703
1704 oam_d_3 = fgauge_read_d_by_v(oam_v_ocv_1);
1705 if (oam_d_3 < 0)
1706 oam_d_3 = 0;
1707 if (oam_d_3 > 100)
1708 oam_d_3 = 100;
1709
1710 oam_r_1 = fgauge_read_r_bat_by_v(oam_v_ocv_1);
1711
1712 oam_v_ocv_2 = fgauge_read_v_by_d(oam_d_2);
1713 oam_r_2 = fgauge_read_r_bat_by_v(oam_v_ocv_2);
1714
1715#if 0
1716 oam_d_4 = (oam_d_2 + oam_d_3) / 2;
1717#else
1718 oam_d_4 = oam_d_3;
1719#endif
1720
1721 gFG_columb = oam_car_2 / 10; /* mAh */
1722
1723 if ((oam_i_1 < 0) || (oam_i_2 < 0))
1724 gFG_Is_Charging = KAL_TRUE;
1725 else
1726 gFG_Is_Charging = KAL_FALSE;
1727
1728#if 0
1729 if (gFG_Is_Charging == KAL_FALSE) {
1730 d5_count_time = 60;
1731 } else {
1732 charging_current = get_charging_setting_current();
1733 charging_current = charging_current / 100;
1734 d5_count_time_rate =
1735 (((gFG_BATT_CAPACITY_aging * 60 * 60 / 100 / (charging_current - 50)) * 10) +
1736 5) / 10;
1737
1738 if (d5_count_time_rate < 1)
1739 d5_count_time_rate = 1;
1740
1741 d5_count_time = d5_count_time_rate;
1742 }
1743#else
1744 d5_count_time = 60;
1745#endif
1746 d5_count = d5_count + delta_time;
1747 if (d5_count >= d5_count_time) {
1748 if (gFG_Is_Charging == KAL_FALSE) {
1749 if (oam_d_3 > oam_d_5) {
1750 oam_d_5 = oam_d_5 + 1;
1751 } else {
1752 if (oam_d_4 > oam_d_5) {
1753 oam_d_5 = oam_d_5 + 1;
1754 }
1755 }
1756 } else {
1757 if (oam_d_5 > oam_d_3) {
1758 oam_d_5 = oam_d_5 - 1;
1759 } else {
1760 if (oam_d_4 < oam_d_5) {
1761 oam_d_5 = oam_d_5 - 1;
1762 }
1763 }
1764 }
1765 d5_count = 0;
1766 oam_d_3_pre = oam_d_3;
1767 oam_d_4_pre = oam_d_4;
1768 }
1769
1770 bm_print(BM_LOG_CRTI, "[oam_run] %d,%d,%d,%d,%d,%d,%d,%d\n",
1771 d5_count, d5_count_time, oam_d_3_pre, oam_d_3, oam_d_4_pre, oam_d_4, oam_d_5,
1772 charging_current);
1773
1774 if (oam_run_i == 0) {
1775 bm_print(BM_LOG_FULL,
1776 "[oam_run] oam_i_1,oam_i_2,oam_car_1,oam_car_2,oam_d_1,oam_d_2,oam_v_ocv_1,oam_d_3,oam_r_1,oam_v_ocv_2,oam_r_2,vol_bat,g_vol_bat_hw_ocv,g_d_hw_ocv\n");
1777 oam_run_i = 1;
1778 }
1779
1780 bm_print(BM_LOG_FULL, "[oam_run] %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
1781 oam_i_1, oam_i_2, oam_car_1, oam_car_2, oam_d_1, oam_d_2, oam_v_ocv_1, oam_d_3,
1782 oam_r_1, oam_v_ocv_2, oam_r_2, vol_bat, g_vol_bat_hw_ocv, g_d_hw_ocv);
1783
1784 bm_print(BM_LOG_FULL, "[oam_total] %d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
1785 gFG_capacity_by_c, gFG_capacity_by_v, gfg_percent_check_point,
1786 oam_d_1, oam_d_2, oam_d_3, oam_d_4, oam_d_5, gFG_capacity_by_c_init, g_d_hw_ocv);
1787
1788 bm_print(BM_LOG_CRTI, "[oam_total_s] %d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", gFG_capacity_by_c, /* 1 */
1789 gFG_capacity_by_v, /* 2 */
1790 gfg_percent_check_point, /* 3 */
1791 (100 - oam_d_1), /* 4 */
1792 (100 - oam_d_2), /* 5 */
1793 (100 - oam_d_3), /* 6 */
1794 (100 - oam_d_4), /* 9 */
1795 (100 - oam_d_5), /* 10 */
1796 gFG_capacity_by_c_init, /* 7 */
1797 (100 - g_d_hw_ocv) /* 8 */
1798 );
1799
1800 bm_print(BM_LOG_FULL, "[oam_total_s_err] %d,%d,%d,%d,%d,%d,%d\n",
1801 (gFG_capacity_by_c - gFG_capacity_by_v),
1802 (gFG_capacity_by_c - gfg_percent_check_point),
1803 (gFG_capacity_by_c - (100 - oam_d_1)),
1804 (gFG_capacity_by_c - (100 - oam_d_2)),
1805 (gFG_capacity_by_c - (100 - oam_d_3)),
1806 (gFG_capacity_by_c - (100 - oam_d_4)), (gFG_capacity_by_c - (100 - oam_d_5))
1807 );
1808
1809 bm_print(BM_LOG_CRTI, "[oam_init_inf] %d, %d, %d, %d, %d, %d\n",
1810 gFG_voltage, (100 - fgauge_read_capacity_by_v(gFG_voltage)), g_rtc_fg_soc,
1811 gFG_DOD0, oam_v_ocv_init, force_get_tbat(KAL_FALSE));
1812
1813 bm_print(BM_LOG_CRTI, "[oam_run_inf] %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n",
1814 oam_v_ocv_1, oam_v_ocv_2, vol_bat, oam_i_1, oam_i_2, oam_r_1, oam_r_2, oam_car_1,
1815 oam_car_2, gFG_BATT_CAPACITY_aging, force_get_tbat(KAL_FALSE), oam_d0);
1816
1817 bm_print(BM_LOG_CRTI, "[oam_result_inf] %d, %d, %d, %d, %d, %d\n",
1818 oam_d_1, oam_d_2, oam_d_3, oam_d_4, oam_d_5, BMT_status.UI_SOC);
1819}
1820
1821/* ============================================================ // */
1822
1823
1824
1825void table_init(void)
1826{
1827 BATTERY_PROFILE_STRUC_P profile_p;
1828 R_PROFILE_STRUC_P profile_p_r_table;
1829
1830 int temperature = force_get_tbat(KAL_FALSE);
1831
1832 /* Re-constructure r-table profile according to current temperature */
1833 profile_p_r_table = fgauge_get_profile_r_table(TEMPERATURE_T);
1834 if (profile_p_r_table == NULL) {
1835 bm_print(BM_LOG_CRTI,
1836 "[FGADC] fgauge_get_profile_r_table : create table fail !\r\n");
1837 }
1838 fgauge_construct_r_table_profile(temperature, profile_p_r_table);
1839
1840 /* Re-constructure battery profile according to current temperature */
1841 profile_p = fgauge_get_profile(TEMPERATURE_T);
1842 if (profile_p == NULL) {
1843 bm_print(BM_LOG_CRTI, "[FGADC] fgauge_get_profile : create table fail !\r\n");
1844 }
1845 fgauge_construct_battery_profile(temperature, profile_p);
1846}
1847
1848kal_int32 auxadc_algo_run(void)
1849{
1850 kal_int32 val = 0;
1851
1852 gFG_voltage = battery_meter_get_battery_voltage(KAL_FALSE);
1853 val = fgauge_read_capacity_by_v(gFG_voltage);
1854
1855 bm_print(BM_LOG_CRTI, "[auxadc_algo_run] %d,%d\n", gFG_voltage, val);
1856
1857 return val;
1858}
1859
1860#if defined(SOC_BY_HW_FG)
1861void update_fg_dbg_tool_value(void)
1862{
1863 g_fg_dbg_bat_volt = gFG_voltage_init;
1864
1865 if (gFG_Is_Charging == KAL_TRUE)
1866 g_fg_dbg_bat_current = 1 - gFG_current - 1;
1867 else
1868 g_fg_dbg_bat_current = gFG_current;
1869
1870 g_fg_dbg_bat_zcv = gFG_voltage;
1871
1872 g_fg_dbg_bat_temp = gFG_temp;
1873
1874 g_fg_dbg_bat_r = gFG_resistance_bat;
1875
1876 g_fg_dbg_bat_car = gFG_columb;
1877
1878 g_fg_dbg_bat_qmax = gFG_BATT_CAPACITY_aging;
1879
1880 g_fg_dbg_d0 = gFG_DOD0;
1881
1882 g_fg_dbg_d1 = gFG_DOD1;
1883
1884 g_fg_dbg_percentage = bat_get_ui_percentage();
1885
1886 g_fg_dbg_percentage_fg = gFG_capacity_by_c;
1887
1888 g_fg_dbg_percentage_voltmode = gfg_percent_check_point;
1889}
1890
1891kal_int32 fgauge_compensate_battery_voltage(kal_int32 ori_voltage)
1892{
1893 kal_int32 ret_compensate_value = 0;
1894
1895 gFG_ori_voltage = ori_voltage;
1896 gFG_resistance_bat = fgauge_read_r_bat_by_v(ori_voltage); /* Ohm */
1897 ret_compensate_value = (gFG_current * (gFG_resistance_bat + R_FG_VALUE)) / 1000;
1898 ret_compensate_value = (ret_compensate_value + (10 / 2)) / 10;
1899
1900 if (gFG_Is_Charging == KAL_TRUE) {
1901 ret_compensate_value = ret_compensate_value - (ret_compensate_value * 2);
1902 }
1903
1904 gFG_compensate_value = ret_compensate_value;
1905
1906 bm_print(BM_LOG_FULL,
1907 "[CompensateVoltage] Ori_voltage:%d, compensate_value:%d, gFG_resistance_bat:%d, gFG_current:%d\r\n",
1908 ori_voltage, ret_compensate_value, gFG_resistance_bat, gFG_current);
1909
1910 return ret_compensate_value;
1911}
1912
1913kal_int32 fgauge_compensate_battery_voltage_recursion(kal_int32 ori_voltage,
1914 kal_int32 recursion_time)
1915{
1916 kal_int32 ret_compensate_value = 0;
1917 kal_int32 temp_voltage_1 = ori_voltage;
1918 kal_int32 temp_voltage_2 = temp_voltage_1;
1919 int i = 0;
1920
1921 for (i = 0; i < recursion_time; i++) {
1922 gFG_resistance_bat = fgauge_read_r_bat_by_v(temp_voltage_2); /* Ohm */
1923 ret_compensate_value = (gFG_current * (gFG_resistance_bat + R_FG_VALUE)) / 1000;
1924 ret_compensate_value = (ret_compensate_value + (10 / 2)) / 10;
1925
1926 if (gFG_Is_Charging == KAL_TRUE) {
1927 ret_compensate_value = ret_compensate_value - (ret_compensate_value * 2);
1928 }
1929 temp_voltage_2 = temp_voltage_1 + ret_compensate_value;
1930
1931 bm_print(BM_LOG_FULL,
1932 "[fgauge_compensate_battery_voltage_recursion] %d,%d,%d,%d\r\n",
1933 temp_voltage_1, temp_voltage_2, gFG_resistance_bat, ret_compensate_value);
1934 }
1935
1936 gFG_resistance_bat = fgauge_read_r_bat_by_v(temp_voltage_2); /* Ohm */
1937 ret_compensate_value =
1938 (gFG_current * (gFG_resistance_bat + R_FG_VALUE + FG_METER_RESISTANCE)) / 1000;
1939 ret_compensate_value = (ret_compensate_value + (10 / 2)) / 10;
1940
1941 if (gFG_Is_Charging == KAL_TRUE) {
1942 ret_compensate_value = ret_compensate_value - (ret_compensate_value * 2);
1943 }
1944
1945 gFG_compensate_value = ret_compensate_value;
1946
1947 bm_print(BM_LOG_FULL, "[fgauge_compensate_battery_voltage_recursion] %d,%d,%d,%d\r\n",
1948 temp_voltage_1, temp_voltage_2, gFG_resistance_bat, ret_compensate_value);
1949
1950 return ret_compensate_value;
1951}
1952
1953
1954kal_int32 fgauge_get_dod0(kal_int32 voltage, kal_int32 temperature, kal_bool bOcv)
1955{
1956 kal_int32 dod0 = 0;
1957 int i = 0, saddles = 0, jj = 0;
1958 BATTERY_PROFILE_STRUC_P profile_p;
1959 R_PROFILE_STRUC_P profile_p_r_table;
1960 int ret = 0;
1961
1962/* R-Table (First Time) */
1963 /* Re-constructure r-table profile according to current temperature */
1964 profile_p_r_table = fgauge_get_profile_r_table(TEMPERATURE_T);
1965 if (profile_p_r_table == NULL) {
1966 bm_print(BM_LOG_CRTI,
1967 "[FGADC] fgauge_get_profile_r_table : create table fail !\r\n");
1968 }
1969 fgauge_construct_r_table_profile(temperature, profile_p_r_table);
1970
1971 /* Re-constructure battery profile according to current temperature */
1972 profile_p = fgauge_get_profile(TEMPERATURE_T);
1973 if (profile_p == NULL) {
1974 bm_print(BM_LOG_CRTI, "[FGADC] fgauge_get_profile : create table fail !\r\n");
1975 return 100;
1976 }
1977 fgauge_construct_battery_profile(temperature, profile_p);
1978
1979 /* Get total saddle points from the battery profile */
1980 saddles = fgauge_get_saddles();
1981
1982 /* If the input voltage is not OCV, compensate to ZCV due to battery loading */
1983 /* Compasate battery voltage from current battery voltage */
1984 jj = 0;
1985 if (bOcv == KAL_FALSE) {
1986 while (gFG_current == 0) {
1987 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);
1988 if (jj > 10)
1989 break;
1990 jj++;
1991 }
1992 /* voltage = voltage + fgauge_compensate_battery_voltage(voltage); //mV */
1993 voltage = voltage + fgauge_compensate_battery_voltage_recursion(voltage, 5); /* mV */
1994 bm_print(BM_LOG_CRTI, "[FGADC] compensate_battery_voltage, voltage=%d\r\n",
1995 voltage);
1996 }
1997 /* If battery voltage is less then mimimum profile voltage, then return 100 */
1998 /* If battery voltage is greater then maximum profile voltage, then return 0 */
1999 if (voltage > (profile_p + 0)->voltage) {
2000 return 0;
2001 }
2002 if (voltage < (profile_p + saddles - 1)->voltage) {
2003 return 100;
2004 }
2005 /* get DOD0 according to current temperature */
2006 for (i = 0; i < saddles - 1; i++) {
2007 if ((voltage <= (profile_p + i)->voltage)
2008 && (voltage >= (profile_p + i + 1)->voltage)) {
2009 dod0 =
2010 (profile_p + i)->percentage +
2011 (((((profile_p + i)->voltage) -
2012 voltage) * (((profile_p + i + 1)->percentage) -
2013 ((profile_p + i)->percentage))
2014 ) / (((profile_p + i)->voltage) - ((profile_p + i + 1)->voltage))
2015 );
2016
2017 break;
2018 }
2019 }
2020
2021 return dod0;
2022}
2023
2024
2025kal_int32 fgauge_update_dod(void)
2026{
2027 kal_int32 FG_dod_1 = 0;
2028 int adjust_coulomb_counter = CAR_TUNE_VALUE;
2029#ifdef Q_MAX_BY_CURRENT
2030 kal_int32 C_0mA=0;
2031 kal_int32 C_400mA=0;
2032 kal_int32 C_FGCurrent=0;
2033#endif
2034
2035 if (gFG_DOD0 > 100) {
2036 gFG_DOD0 = 100;
2037 bm_print(BM_LOG_FULL, "[fgauge_update_dod] gFG_DOD0 set to 100, gFG_columb=%d\r\n",
2038 gFG_columb);
2039 } else if (gFG_DOD0 < 0) {
2040 gFG_DOD0 = 0;
2041 bm_print(BM_LOG_FULL, "[fgauge_update_dod] gFG_DOD0 set to 0, gFG_columb=%d\r\n",
2042 gFG_columb);
2043 } else {
2044 }
2045
2046 gFG_temp = force_get_tbat(KAL_FALSE);
2047
2048 if (temperature_change == 1) {
2049 gFG_BATT_CAPACITY = fgauge_get_Q_max(gFG_temp);
2050 bm_print(BM_LOG_CRTI,
2051 "[fgauge_update_dod] gFG_BATT_CAPACITY=%d, gFG_BATT_CAPACITY_aging=%d, gFG_BATT_CAPACITY_init_high_current=%d\r\n",
2052 gFG_BATT_CAPACITY, gFG_BATT_CAPACITY_aging,
2053 gFG_BATT_CAPACITY_init_high_current);
2054 temperature_change = 0;
2055 }
2056#if 0
2057 C_0mA = fgauge_get_Q_max(gFG_temp);
2058 C_400mA = fgauge_get_Q_max_high_current(gFG_temp);
2059 C_FGCurrent = C_0mA - (C_0mA-C_400mA) * gFG_current_AVG / 4000;
2060 if (C_FGCurrent!=0)
2061 FG_dod_1 = gFG_DOD0 - ((gFG_columb*100)/gFG_BATT_CAPACITY_aging)*C_0mA/C_FGCurrent;
2062
2063 bm_print(BM_LOG_CRTI, "[fgauge_update_dod] FG_dod_1=%d, adjust_coulomb_counter=%d, gFG_columb=%d, gFG_DOD0=%d, gFG_temp=%d, gFG_BATT_CAPACITY=%d, C_0mA=%d, C_400mA=%d, C_FGCurrent=%d, gFG_current_AVG=%d\n",
2064 FG_dod_1, adjust_coulomb_counter, gFG_columb, gFG_DOD0, gFG_temp, gFG_BATT_CAPACITY, C_0mA, C_400mA, C_FGCurrent, gFG_current_AVG);
2065#else
2066 FG_dod_1 = gFG_DOD0 - ((gFG_columb * 100) / gFG_BATT_CAPACITY_aging);
2067
2068 bm_print(BM_LOG_FULL,
2069 "[fgauge_update_dod] FG_dod_1=%d, adjust_coulomb_counter=%d, gFG_columb=%d, gFG_DOD0=%d, gFG_temp=%d, gFG_BATT_CAPACITY=%d\r\n",
2070 FG_dod_1, adjust_coulomb_counter, gFG_columb, gFG_DOD0, gFG_temp,
2071 gFG_BATT_CAPACITY);
2072#endif
2073 if (FG_dod_1 > 100) {
2074 FG_dod_1 = 100;
2075 bm_print(BM_LOG_FULL, "[fgauge_update_dod] FG_dod_1 set to 100, gFG_columb=%d\r\n",
2076 gFG_columb);
2077 } else if (FG_dod_1 < 0) {
2078 FG_dod_1 = 0;
2079 bm_print(BM_LOG_FULL, "[fgauge_update_dod] FG_dod_1 set to 0, gFG_columb=%d\r\n",
2080 gFG_columb);
2081 } else {
2082 }
2083
2084 return FG_dod_1;
2085}
2086
2087
2088kal_int32 fgauge_read_capacity(kal_int32 type)
2089{
2090 kal_int32 voltage;
2091 kal_int32 temperature;
2092 kal_int32 dvalue = 0;
4b9e9796
S
2093
2094#ifndef CUST_DISABLE_CAPACITY_OCV2CV_TRANSFORM
2095 kal_int32 C_0mA = 0;
2096 kal_int32 C_400mA = 0;
2097 kal_int32 dvalue_new = 0;
2098#endif
2099
6fa3eb70
S
2100 kal_int32 temp_val = 0;
2101
2102 if (type == 0) /* for initialization */
2103 {
2104 /* Use voltage to calculate capacity */
2105 voltage = battery_meter_get_battery_voltage(KAL_TRUE); /* in unit of mV */
2106 temperature = force_get_tbat(KAL_FALSE);
2107 dvalue = fgauge_get_dod0(voltage, temperature, KAL_FALSE); /* need compensate vbat */
2108 } else {
2109 /* Use DOD0 and columb counter to calculate capacity */
2110 dvalue = fgauge_update_dod(); /* DOD1 = DOD0 + (-CAR)/Qmax */
2111 }
2112
2113 gFG_DOD1 = dvalue;
4b9e9796
S
2114
2115#ifndef CUST_DISABLE_CAPACITY_OCV2CV_TRANSFORM
2116 /* User View on HT~LT---------------------------------------------------------- */
2117 gFG_temp = force_get_tbat(KAL_FALSE);
2118 C_0mA = fgauge_get_Q_max(gFG_temp);
2119 C_400mA = fgauge_get_Q_max_high_current(gFG_temp);
2120 if (C_0mA > C_400mA) {
2121 dvalue_new = (100 - dvalue) - (((C_0mA - C_400mA) * (dvalue)) / C_400mA);
2122 dvalue = 100 - dvalue_new;
2123 }
2124 bm_print(BM_LOG_FULL, "[fgauge_read_capacity] %d,%d,%d,%d,%d,D1=%d,D0=%d\r\n",
2125 gFG_temp, C_0mA, C_400mA, dvalue, dvalue_new, gFG_DOD1, gFG_DOD0);
2126 /* ---------------------------------------------------------------------------- */
2127#endif /* CUST_DISABLE_CAPACITY_OCV2CV_TRANSFORM */
6fa3eb70
S
2128 temp_val = dvalue;
2129 dvalue = 100 - temp_val;
2130
2131 if (dvalue <= 1) {
2132 dvalue = 1;
2133 bm_print(BM_LOG_FULL, "[fgauge_read_capacity] dvalue<=1 and set dvalue=1 !!\r\n");
2134 }
2135
2136 return dvalue;
2137}
2138
2139
2140void fg_voltage_mode(void)
2141{
2142#if defined(CONFIG_POWER_EXT)
2143#else
2144 if (bat_is_charger_exist() == KAL_TRUE) {
2145 /* SOC only UP when charging */
2146 if (gFG_capacity_by_v > gfg_percent_check_point) {
2147 gfg_percent_check_point++;
2148 }
2149 } else {
2150 /* SOC only Done when dis-charging */
2151 if (gFG_capacity_by_v < gfg_percent_check_point) {
2152 gfg_percent_check_point--;
2153 }
2154 }
2155
2156 bm_print(BM_LOG_FULL,
2157 "[FGADC_VoltageMothod] gFG_capacity_by_v=%d,gfg_percent_check_point=%d\r\n",
2158 gFG_capacity_by_v, gfg_percent_check_point);
2159#endif
2160}
2161
2162
2163void fgauge_algo_run(void)
2164{
2165 int i = 0;
2166 int ret = 0;
2167#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
2168 int columb_delta = 0;
2169 int charge_current = 0;
2170#endif
2171
2172 /* Reconstruct table if temp changed; */
2173 fgauge_construct_table_by_temp();
2174
2175/* 1. Get Raw Data */
2176 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);
2177 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN, &gFG_Is_Charging);
2178
2179 gFG_voltage = battery_meter_get_battery_voltage(KAL_FALSE);
2180 gFG_voltage_init = gFG_voltage;
2181 gFG_voltage = gFG_voltage + fgauge_compensate_battery_voltage_recursion(gFG_voltage, 5); /* mV */
2182 gFG_voltage = gFG_voltage + OCV_BOARD_COMPESATE;
2183
2184 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &gFG_columb);
2185
2186#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
2187 if (gFG_Is_Charging) {
2188 charge_current -= gFG_current;
2189 if (charge_current < gFG_min_current)
2190 gFG_min_current = charge_current;
2191 } else {
2192 if (gFG_current > gFG_max_current)
2193 gFG_max_current = gFG_current;
2194 }
2195
2196 columb_delta = gFG_pre_columb_count - gFG_columb;
2197
2198 if (columb_delta < 0)
2199 columb_delta = columb_delta - 2 * columb_delta; /* absolute value */
2200
2201 gFG_pre_columb_count = gFG_columb;
2202 gFG_columb_sum += columb_delta;
2203
2204 /* should we use gFG_BATT_CAPACITY or gFG_BATT_CAPACITY_aging ?? */
2205 if (gFG_columb_sum >= 2 * gFG_BATT_CAPACITY_aging) {
2206 gFG_battery_cycle++;
2207 gFG_columb_sum -= 2 * gFG_BATT_CAPACITY_aging;
2208 bm_print(BM_LOG_CRTI, "Update battery cycle count to %d. \r\n", gFG_battery_cycle);
2209 }
2210 bm_print(BM_LOG_FULL, "@@@ bat cycle count %d, columb sum %d. \r\n", gFG_battery_cycle,
2211 gFG_columb_sum);
2212#endif
2213
2214 // add by willcai 2014-12-18 begin
2215 if(BMT_status.charger_exist == KAL_FALSE) {
2216 if(gFG_Is_offset_init == KAL_FALSE) {
2217 for (i=0; i<FG_VBAT_AVERAGE_SIZE; i++) {
2218 FGvbatVoltageBuffer[i] = gFG_voltage;
2219 }
2220
2221 FGbatteryVoltageSum = gFG_voltage * FG_VBAT_AVERAGE_SIZE;
2222 gFG_voltage_AVG = gFG_voltage;
2223 gFG_Is_offset_init = KAL_TRUE;
2224 }
2225/* 1.1 Average FG_voltage */
2226 /**************** Averaging : START ****************/
2227 if (gFG_voltage >= gFG_voltage_AVG) {
2228 gFG_vbat_offset = (gFG_voltage - gFG_voltage_AVG);
2229 } else {
2230 gFG_vbat_offset = (gFG_voltage_AVG - gFG_voltage);
2231 }
2232
2233 if (gFG_vbat_offset <= MinErrorOffset) {
2234 FGbatteryVoltageSum -= FGvbatVoltageBuffer[FGbatteryIndex];
2235 FGbatteryVoltageSum += gFG_voltage;
2236 FGvbatVoltageBuffer[FGbatteryIndex] = gFG_voltage;
2237
2238 gFG_voltage_AVG = FGbatteryVoltageSum / FG_VBAT_AVERAGE_SIZE;
2239 gFG_voltage = gFG_voltage_AVG;
2240
2241 FGbatteryIndex++;
2242 if (FGbatteryIndex >= FG_VBAT_AVERAGE_SIZE)
2243 FGbatteryIndex = 0;
2244
2245 bm_print(BM_LOG_FULL, "[FG_BUFFER] ");
2246 for (i = 0; i < FG_VBAT_AVERAGE_SIZE; i++) {
2247 bm_print(BM_LOG_FULL, "%d,", FGvbatVoltageBuffer[i]);
2248 }
2249 bm_print(BM_LOG_FULL, "\r\n");
2250 } else {
2251 bm_print(BM_LOG_FULL, "[FG] Over MinErrorOffset:V=%d,Avg_V=%d, ", gFG_voltage,
2252 gFG_voltage_AVG);
2253
2254 gFG_voltage = gFG_voltage_AVG;
2255
2256 bm_print(BM_LOG_FULL, "Avg_V need write back to V : V=%d,Avg_V=%d.\r\n",
2257 gFG_voltage, gFG_voltage_AVG);
2258 }
2259 } else {
2260 gFG_Is_offset_init = KAL_FALSE;
2261 }
2262#ifdef Q_MAX_BY_CURRENT
2263/* 1.2 Average FG_current */
2264 /**************** Averaging : START ****************/
2265 if (gFG_current_AVG == 0) {
2266 for (i=0; i<FG_CURRENT_AVERAGE_SIZE; i++) {
2267 FGCurrentBuffer[i] = gFG_current;
2268 }
2269
2270 FGCurrentSum = gFG_current * FG_CURRENT_AVERAGE_SIZE;
2271 gFG_current_AVG = gFG_current;
2272 } else {
2273 FGCurrentSum -= FGCurrentBuffer[FGCurrentIndex];
2274 FGCurrentSum += gFG_current;
2275 FGCurrentBuffer[FGCurrentIndex] = gFG_current;
2276
2277 gFG_current_AVG = FGCurrentSum / FG_CURRENT_AVERAGE_SIZE;
2278
2279 FGCurrentIndex++;
2280 if (FGCurrentIndex >= FG_CURRENT_AVERAGE_SIZE)
2281 FGCurrentIndex = 0;
2282
2283 bm_print(BM_LOG_FULL, "[FG_BUFFER] ");
2284 for (i=0; i<FG_CURRENT_AVERAGE_SIZE; i++) {
2285 bm_print(BM_LOG_FULL, "%d,", FGCurrentBuffer[i]);
2286 }
2287 bm_print(BM_LOG_FULL, "\n");
2288 }
2289#endif
2290/* 2. Calculate battery capacity by VBAT */
2291 gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage);
2292
2293/* 3. Calculate battery capacity by Coulomb Counter */
2294 gFG_capacity_by_c = fgauge_read_capacity(1);
2295
2296/* 4. voltage mode */
2297 if (volt_mode_update_timer >= volt_mode_update_time_out) {
2298 volt_mode_update_timer = 0;
2299
2300 fg_voltage_mode();
2301 } else {
2302 volt_mode_update_timer++;
2303 }
2304
2305/* 5. Logging */
2306 bm_print(BM_LOG_CRTI,
2307 "[FGADC] %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",
2308 gFG_Is_Charging, gFG_current, gFG_columb, gFG_voltage, gFG_capacity_by_v,
2309 gFG_capacity_by_c, gFG_capacity_by_c_init, gFG_BATT_CAPACITY,
2310 gFG_BATT_CAPACITY_aging, gFG_compensate_value, gFG_ori_voltage,
2311 OCV_BOARD_COMPESATE, R_FG_BOARD_SLOPE, gFG_voltage_init, MinErrorOffset, gFG_DOD0,
2312 gFG_DOD1, CAR_TUNE_VALUE, AGING_TUNING_VALUE);
2313 update_fg_dbg_tool_value();
2314}
2315
2316void fgauge_algo_run_init(void)
2317{
2318 int i = 0;
2319 int ret = 0;
2320
2321#ifdef INIT_SOC_BY_SW_SOC
2322 kal_bool charging_enable = KAL_FALSE;
2323#if defined (CONFIG_MTK_KERNEL_POWER_OFF_CHARGING) && !defined(SWCHR_POWER_PATH)
2324 if(LOW_POWER_OFF_CHARGING_BOOT != g_boot_mode)
2325#endif
2326 /*stop charging for vbat measurement*/
2327 battery_charging_control(CHARGING_CMD_ENABLE,&charging_enable);
2328
2329 msleep(50);
2330#endif
2331/* 1. Get Raw Data */
2332 gFG_voltage = battery_meter_get_battery_voltage(KAL_TRUE);
2333 gFG_voltage_init = gFG_voltage;
2334 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);
2335 ret=battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN, &gFG_Is_Charging);
2336
2337 gFG_voltage = gFG_voltage + fgauge_compensate_battery_voltage_recursion(gFG_voltage, 5); /* mV */
2338 gFG_voltage = gFG_voltage + OCV_BOARD_COMPESATE;
2339
2340 bm_print(BM_LOG_CRTI, "[FGADC] SWOCV : %d,%d,%d,%d,%d,%d\n",
2341 gFG_voltage_init, gFG_voltage, gFG_current, gFG_Is_Charging, gFG_resistance_bat,
2342 gFG_compensate_value);
2343#ifdef INIT_SOC_BY_SW_SOC
2344 charging_enable = KAL_TRUE;
2345 battery_charging_control(CHARGING_CMD_ENABLE,&charging_enable);
2346#endif
2347 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &gFG_columb);
2348
2349/* 1.1 Average FG_voltage */
2350 for (i = 0; i < FG_VBAT_AVERAGE_SIZE; i++) {
2351 FGvbatVoltageBuffer[i] = gFG_voltage;
2352 }
2353
2354 FGbatteryVoltageSum = gFG_voltage * FG_VBAT_AVERAGE_SIZE;
2355 gFG_voltage_AVG = gFG_voltage;
2356
2357#ifdef Q_MAX_BY_CURRENT
2358/* 1.2 Average FG_current */
2359 for (i=0; i<FG_CURRENT_AVERAGE_SIZE; i++) {
2360 FGCurrentBuffer[i] = gFG_current;
2361 }
2362
2363 FGCurrentSum = gFG_current * FG_CURRENT_AVERAGE_SIZE;
2364 gFG_current_AVG = gFG_current;
2365#endif
2366
2367/* 2. Calculate battery capacity by VBAT */
2368 gFG_capacity_by_v = fgauge_read_capacity_by_v(gFG_voltage);
2369 gFG_capacity_by_v_init = gFG_capacity_by_v;
2370
2371/* 3. Calculate battery capacity by Coulomb Counter */
2372 gFG_capacity_by_c = fgauge_read_capacity(1);
2373
2374/* 4. update DOD0 */
2375
2376 dod_init();
2377
2378 gFG_current_auto_detect_R_fg_count = 0;
2379
2380 for (i = 0; i < 10; i++) {
2381 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);
2382
2383 gFG_current_auto_detect_R_fg_total += gFG_current;
2384 gFG_current_auto_detect_R_fg_count++;
2385 }
2386
2387 /* double check */
2388 if (gFG_current_auto_detect_R_fg_total <= 0) {
2389 bm_print(BM_LOG_CRTI, "gFG_current_auto_detect_R_fg_total=0, need double check\n");
2390
2391 gFG_current_auto_detect_R_fg_count = 0;
2392
2393 for (i = 0; i < 10; i++) {
2394 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);
2395
2396 gFG_current_auto_detect_R_fg_total += gFG_current;
2397 gFG_current_auto_detect_R_fg_count++;
2398 }
2399 }
2400
2401 gFG_current_auto_detect_R_fg_result =
2402 gFG_current_auto_detect_R_fg_total / gFG_current_auto_detect_R_fg_count;
2403#if !defined(DISABLE_RFG_EXIST_CHECK)
2404 if (gFG_current_auto_detect_R_fg_result <= CURRENT_DETECT_R_FG) {
2405 g_auxadc_solution = 1;
2406
2407 bm_print(BM_LOG_CRTI,
2408 "[FGADC] Detect NO Rfg, use AUXADC report. (%d=%d/%d)(%d)\r\n",
2409 gFG_current_auto_detect_R_fg_result, gFG_current_auto_detect_R_fg_total,
2410 gFG_current_auto_detect_R_fg_count, g_auxadc_solution);
2411 } else {
2412 if (g_auxadc_solution == 0) {
2413 g_auxadc_solution = 0;
2414
2415 bm_print(BM_LOG_CRTI,
2416 "[FGADC] Detect Rfg, use FG report. (%d=%d/%d)(%d)\r\n",
2417 gFG_current_auto_detect_R_fg_result,
2418 gFG_current_auto_detect_R_fg_total,
2419 gFG_current_auto_detect_R_fg_count, g_auxadc_solution);
2420 } else {
2421 bm_print(BM_LOG_CRTI,
2422 "[FGADC] Detect Rfg, but use AUXADC report. due to g_auxadc_solution=%d \r\n",
2423 g_auxadc_solution);
2424 }
2425 }
2426#endif
2427/* 5. Logging */
2428 bm_print(BM_LOG_CRTI,
2429 "[FGADC] %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",
2430 gFG_Is_Charging, gFG_current, gFG_columb, gFG_voltage, gFG_capacity_by_v,
2431 gFG_capacity_by_c, gFG_capacity_by_c_init, gFG_BATT_CAPACITY,
2432 gFG_BATT_CAPACITY_aging, gFG_compensate_value, gFG_ori_voltage,
2433 OCV_BOARD_COMPESATE, R_FG_BOARD_SLOPE, gFG_voltage_init, MinErrorOffset, gFG_DOD0,
2434 gFG_DOD1, CAR_TUNE_VALUE, AGING_TUNING_VALUE);
2435 update_fg_dbg_tool_value();
2436}
2437
2438void fgauge_initialization(void)
2439{
2440#if defined(CONFIG_POWER_EXT)
2441#else
2442 int i = 0;
2443 kal_uint32 ret = 0;
2444
2445 /* gFG_BATT_CAPACITY_init_high_current = fgauge_get_Q_max_high_current(25); */
2446 /* gFG_BATT_CAPACITY_aging = fgauge_get_Q_max(25); */
2447
2448 /* 1. HW initialization */
2449 ret = battery_meter_ctrl(BATTERY_METER_CMD_HW_FG_INIT, NULL);
2450
2451 /* 2. SW algorithm initialization */
2452 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &gFG_voltage);
2453
2454 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);
2455 i = 0;
2456 while (gFG_current == 0) {
2457 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &gFG_current);
2458 if (i > 10) {
2459 bm_print(BM_LOG_CRTI, "[fgauge_initialization] gFG_current == 0\n");
2460 break;
2461 }
2462 i++;
2463 }
2464
2465 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &gFG_columb);
2466 fgauge_construct_battery_profile_init();
2467 gFG_temp = force_get_tbat(KAL_FALSE);
2468 gFG_capacity = fgauge_read_capacity(0);
2469
2470 gFG_capacity_by_c_init = gFG_capacity;
2471 gFG_capacity_by_c = gFG_capacity;
2472 gFG_capacity_by_v = gFG_capacity;
2473
2474 gFG_DOD0 = 100 - gFG_capacity;
2475
2476 gFG_BATT_CAPACITY = fgauge_get_Q_max(gFG_temp);
2477
2478 gFG_BATT_CAPACITY_init_high_current = fgauge_get_Q_max_high_current(gFG_temp);
2479 gFG_BATT_CAPACITY_aging = fgauge_get_Q_max(gFG_temp);
2480
2481 ret = battery_meter_ctrl(BATTERY_METER_CMD_DUMP_REGISTER, NULL);
2482
2483 bm_print(BM_LOG_CRTI, "[fgauge_initialization] Done\n");
2484#endif
2485}
2486#endif
2487
2488kal_int32 get_dynamic_period(int first_use, int first_wakeup_time, int battery_capacity_level)
2489{
2490#if defined(CONFIG_POWER_EXT)
2491
2492 return first_wakeup_time;
2493
2494#elif defined(SOC_BY_AUXADC) || defined(SOC_BY_SW_FG)
2495
2496 kal_int32 vbat_val = 0;
2497
2498#ifdef CONFIG_MTK_POWER_EXT_DETECT
2499 if (KAL_TRUE == bat_is_ext_power())
2500 return NORMAL_WAKEUP_PERIOD;
2501#endif
2502
2503 vbat_val = g_sw_vbat_temp;
2504
2505 /* change wake up period when system suspend. */
2506 if (vbat_val > VBAT_NORMAL_WAKEUP) /* 3.6v */
2507 g_spm_timer = NORMAL_WAKEUP_PERIOD; /* 90 min */
2508 else if (vbat_val > VBAT_LOW_POWER_WAKEUP) /* 3.5v */
2509 g_spm_timer = LOW_POWER_WAKEUP_PERIOD; /* 5 min */
2510 else
2511 g_spm_timer = CLOSE_POWEROFF_WAKEUP_PERIOD; /* 0.5 min */
2512
2513
2514
2515 bm_print(BM_LOG_CRTI, "vbat_val=%d, g_spm_timer=%d\n", vbat_val, g_spm_timer);
2516
2517 return g_spm_timer;
2518#else
2519
2520 kal_int32 car_instant = 0;
2521 kal_int32 current_instant = 0;
2522 static kal_int32 car_sleep=0x12345678;
2523 kal_int32 car_wakeup = 0;
2524 static kal_int32 last_time=0;
2525
2526 kal_int32 ret_val = -1;
2527 int check_fglog = 0;
2528 kal_int32 I_sleep = 0;
2529 kal_int32 new_time = 0;
2530 kal_int32 vbat_val = 0;
2531 int ret = 0;
2532
2533 check_fglog = Enable_FGADC_LOG;
2534 if (check_fglog == 0) {
2535 /* Enable_FGADC_LOG=1; */
2536 }
2537
2538
2539 vbat_val = g_sw_vbat_temp;
2540
2541 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &current_instant);
2542
2543 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &car_instant);
2544
2545 if (check_fglog == 0) {
2546 /* Enable_FGADC_LOG=0; */
2547 }
2548 if (car_instant < 0) {
2549 car_instant = car_instant - (car_instant * 2);
2550 }
2551
2552 if (vbat_val > VBAT_NORMAL_WAKEUP) /* 3.6v */
2553 {
2554 car_wakeup = car_instant;
2555
2556 if (last_time == 0)
2557 last_time = 1;
2558
2559 if (car_sleep > car_wakeup || car_sleep == 0x12345678) {
2560 car_sleep = car_wakeup;
2561 bm_print(BM_LOG_CRTI, "[get_dynamic_period] reset car_sleep\n");
2562 }
2563
2564 I_sleep = ((car_wakeup - car_sleep) * 3600) / last_time; /* unit: second */
2565
2566 if (I_sleep == 0) {
2567 if (check_fglog == 0) {
2568 /* Enable_FGADC_LOG=1; */
2569 }
2570
2571 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &I_sleep);
2572
2573 I_sleep = I_sleep / 10;
2574 if (check_fglog == 0) {
2575 /* Enable_FGADC_LOG=0; */
2576 }
2577 }
2578
2579 if (I_sleep == 0) {
2580 new_time = first_wakeup_time;
2581 } else {
2582 new_time =
2583 ((gFG_BATT_CAPACITY * battery_capacity_level * 3600) / 100) / I_sleep;
2584 }
2585 ret_val = new_time;
2586
2587 if (ret_val == 0)
2588 ret_val = first_wakeup_time;
2589
2590 bm_print(BM_LOG_CRTI,
2591 "[get_dynamic_period] car_instant=%d, car_wakeup=%d, car_sleep=%d, I_sleep=%d, gFG_BATT_CAPACITY=%d, last_time=%d, new_time=%d\r\n",
2592 car_instant, car_wakeup, car_sleep, I_sleep, gFG_BATT_CAPACITY, last_time,
2593 new_time);
2594
2595 /* update parameter */
2596 car_sleep = car_wakeup;
2597 last_time = ret_val;
2598 g_spm_timer = ret_val;
2599 } else if (vbat_val > VBAT_LOW_POWER_WAKEUP) { /* 3.5v */
2600 g_spm_timer = LOW_POWER_WAKEUP_PERIOD; /* 5 min */
2601 } else {
2602 g_spm_timer = CLOSE_POWEROFF_WAKEUP_PERIOD; /* 0.5 min */
2603 }
2604
2605 bm_print(BM_LOG_CRTI, "vbat_val=%d, g_spm_timer=%d\n", vbat_val, g_spm_timer);
2606 return g_spm_timer;
2607
2608#endif
2609}
2610
2611/* ============================================================ // */
2612kal_int32 battery_meter_get_battery_voltage(kal_bool update)
2613{
2614 int ret = 0;
2615 int val = 5;
2616 static int pre_val = -1;
2617
2618 if (update == KAL_TRUE || pre_val == -1) {
2619 val = 5; /* set avg times */
2620 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &val);
2621 pre_val = val;
2622 } else {
2623 val = pre_val;
2624 }
2625 g_sw_vbat_temp = val;
2626
2627#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
2628 if (g_sw_vbat_temp > gFG_max_voltage) {
2629 gFG_max_voltage = g_sw_vbat_temp;
2630 }
2631
2632 if (g_sw_vbat_temp < gFG_min_voltage) {
2633 gFG_min_voltage = g_sw_vbat_temp;
2634 }
2635#endif
2636
2637 return val;
2638}
2639
2640kal_int32 battery_meter_get_charging_current_imm(void)
2641{
2642 int ret;
2643 kal_int32 ADC_I_SENSE=1; // 1 measure time
2644 kal_int32 ADC_BAT_SENSE=1; // 1 measure time
2645 int ICharging=0;
2646
2647 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &ADC_BAT_SENSE);
2648 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_I_SENSE, &ADC_I_SENSE);
2649
2650 ICharging = (ADC_I_SENSE - ADC_BAT_SENSE + g_I_SENSE_offset)*1000/CUST_R_SENSE;
2651 return ICharging;
2652}
2653
2654kal_int32 battery_meter_get_charging_current(void)
2655{
2656#ifdef DISABLE_CHARGING_CURRENT_MEASURE
2657 return 0;
4b9e9796
S
2658/* [PLATFORM]-Add-BEGIN by TCTSZ.leo.guo, 2015.06.10, Added measure current feature */
2659#else
6fa3eb70
S
2660 kal_int32 ADC_BAT_SENSE_tmp[10] =
2661 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2662 kal_int32 ADC_BAT_SENSE_sum = 0;
2663 kal_int32 ADC_BAT_SENSE = 0;
2664 kal_int32 ADC_I_SENSE_tmp[10] =
2665 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2666 kal_int32 ADC_I_SENSE_sum = 0;
2667 kal_int32 ADC_I_SENSE = 0;
2668 int repeat = 10;
2669 int i = 0;
2670 int j = 0;
2671 kal_int32 temp = 0;
2672 int ICharging = 0;
2673 int ret = 0;
2674 int val = 1;
2675
2676 for (i = 0; i < repeat; i++) {
2677 val = 1; /* set avg times */
2678 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_SENSE, &val);
2679 ADC_BAT_SENSE_tmp[i] = val;
2680
2681 val = 1; /* set avg times */
2682 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_I_SENSE, &val);
2683 ADC_I_SENSE_tmp[i] = val;
2684
2685 ADC_BAT_SENSE_sum += ADC_BAT_SENSE_tmp[i];
2686 ADC_I_SENSE_sum += ADC_I_SENSE_tmp[i];
2687 }
2688
2689 /* sorting BAT_SENSE */
2690 for (i = 0; i < repeat; i++) {
2691 for (j = i; j < repeat; j++) {
2692 if (ADC_BAT_SENSE_tmp[j] < ADC_BAT_SENSE_tmp[i]) {
2693 temp = ADC_BAT_SENSE_tmp[j];
2694 ADC_BAT_SENSE_tmp[j] = ADC_BAT_SENSE_tmp[i];
2695 ADC_BAT_SENSE_tmp[i] = temp;
2696 }
2697 }
2698 }
2699
2700 bm_print(BM_LOG_FULL, "[g_Get_I_Charging:BAT_SENSE]\r\n");
2701 for (i = 0; i < repeat; i++) {
2702 bm_print(BM_LOG_FULL, "%d,", ADC_BAT_SENSE_tmp[i]);
2703 }
2704 bm_print(BM_LOG_FULL, "\r\n");
2705
2706 /* sorting I_SENSE */
2707 for (i = 0; i < repeat; i++) {
2708 for (j = i; j < repeat; j++) {
2709 if (ADC_I_SENSE_tmp[j] < ADC_I_SENSE_tmp[i]) {
2710 temp = ADC_I_SENSE_tmp[j];
2711 ADC_I_SENSE_tmp[j] = ADC_I_SENSE_tmp[i];
2712 ADC_I_SENSE_tmp[i] = temp;
2713 }
2714 }
2715 }
2716
2717 bm_print(BM_LOG_FULL, "[g_Get_I_Charging:I_SENSE]\r\n");
2718 for (i = 0; i < repeat; i++) {
2719 bm_print(BM_LOG_FULL, "%d,", ADC_I_SENSE_tmp[i]);
2720 }
2721 bm_print(BM_LOG_FULL, "\r\n");
2722
2723 ADC_BAT_SENSE_sum -= ADC_BAT_SENSE_tmp[0];
2724 ADC_BAT_SENSE_sum -= ADC_BAT_SENSE_tmp[9];
2725 ADC_BAT_SENSE = ADC_BAT_SENSE_sum / (repeat - 2);
2726
2727 bm_print(BM_LOG_FULL, "[g_Get_I_Charging] ADC_BAT_SENSE=%d\r\n", ADC_BAT_SENSE);
2728
2729 ADC_I_SENSE_sum -= ADC_I_SENSE_tmp[0];
2730 ADC_I_SENSE_sum -= ADC_I_SENSE_tmp[9];
2731 ADC_I_SENSE = ADC_I_SENSE_sum / (repeat - 2);
2732
2733 bm_print(BM_LOG_FULL, "[g_Get_I_Charging] ADC_I_SENSE(Before)=%d\r\n", ADC_I_SENSE);
2734
2735
2736 bm_print(BM_LOG_FULL, "[g_Get_I_Charging] ADC_I_SENSE(After)=%d\r\n", ADC_I_SENSE);
2737
2738 if (ADC_I_SENSE > ADC_BAT_SENSE) {
2739 ICharging = (ADC_I_SENSE - ADC_BAT_SENSE + g_I_SENSE_offset) * 1000 / CUST_R_SENSE;
2740 } else {
2741 ICharging = 0;
2742 }
2743
2744 return ICharging;
6fa3eb70 2745#endif
4b9e9796 2746/* [PLATFORM]-Add-END by TCTSZ.leo.guo, 2015.06.10 */
6fa3eb70
S
2747}
2748
2749kal_int32 battery_meter_get_battery_current(void)
2750{
2751 int ret = 0;
2752 kal_int32 val = 0;
2753
2754 if (g_auxadc_solution == 1)
2755 val = oam_i_2;
2756 else
2757 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &val);
2758
2759 return val;
2760}
2761
2762kal_bool battery_meter_get_battery_current_sign(void)
2763{
2764 int ret = 0;
2765 kal_bool val = 0;
2766
2767 if (g_auxadc_solution == 1)
2768 val = 0; /* discharging */
2769 else
2770 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN, &val);
2771
2772 return val;
2773}
2774
2775kal_int32 battery_meter_get_car(void)
2776{
2777 int ret = 0;
2778 kal_int32 val = 0;
2779
2780 if (g_auxadc_solution == 1)
2781 val = oam_car_2;
2782 else
2783 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &val);
2784
2785 return val;
2786}
2787
2788kal_int32 battery_meter_get_battery_temperature(void)
2789{
2790#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
2791 kal_int32 batt_temp = force_get_tbat(KAL_TRUE);
2792
2793 if (batt_temp > gFG_max_temperature)
2794 gFG_max_temperature = batt_temp;
2795 if (batt_temp < gFG_min_temperature)
2796 gFG_min_temperature = batt_temp;
2797
2798 return batt_temp;
2799#else
2800//[FEATURE]-Add-BEGIN by huichen@tcl.com,04/03/2015,mini sw pr964182
2801#ifdef TARGET_BUILD_MMITEST
2802return 25;
2803#else
2804 return force_get_tbat(KAL_TRUE);
2805#endif
2806//[FEATURE]-Add-END by huichen@tcl.com,04/03/2015,mini sw pr964182
2807
2808#endif
2809}
2810
2811kal_int32 battery_meter_get_charger_voltage(void)
2812{
2813 int ret = 0;
2814 int val = 0;
2815
2816 val = 5; /* set avg times */
2817 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_CHARGER, &val);
2818
2819 /* val = (((R_CHARGER_1+R_CHARGER_2)*100*val)/R_CHARGER_2)/100; */
2820 return val;
2821}
2822
2823kal_int32 battery_meter_get_battery_soc(void)
2824{
2825#if (OAM_D5 == 1)
2826 return (100-oam_d_5);
2827#else
2828 return (100-oam_d_2);
2829#endif
2830}
2831
2832#ifdef CUST_CAPACITY_OCV2CV_TRANSFORM
2833void battery_meter_set_reset_soc(kal_bool bUSE_UI_SOC)
2834{
2835 g_USE_UI_SOC = bUSE_UI_SOC;
2836}
2837
2838kal_int32 battery_meter_trans_battery_percentage(kal_int32 d_val)
2839{
2840 kal_int32 d_val_temp = 0;
2841 kal_int32 d_val_new = 0;
2842 kal_int32 temp_val = 0;
2843 kal_int32 C_0mA=0;
2844 kal_int32 C_400mA=0;
2845 kal_int32 i_avg_current = 0;
2846
2847 //User View on HT~LT----------------------------------------------------------
2848 d_val_temp = d_val;
2849 temp_val = battery_meter_get_battery_temperature();
2850 C_0mA = fgauge_get_Q_max(temp_val);
4b9e9796
S
2851/* [BUGFIX]-Add-BEGIN by TCTSZ.leo.guo, 06/25/2015, Fixed voltage calculate to report error soc. */
2852 if(gFG_Is_Charging == KAL_TRUE)
2853 return d_val;
2854/* [BUGFIX]-Add-BEGIN by TCTSZ.leo.guo, 06/25/2015 */
6fa3eb70
S
2855 // discharging and current > 600ma
2856 i_avg_current = g_currentfactor * 6000/100;
2857 if(KAL_FALSE == gFG_Is_Charging && g_currentfactor > 100)
2858 C_400mA = fgauge_get_Q_max_high_current_by_current(i_avg_current, temp_val);
2859 else
2860 C_400mA = fgauge_get_Q_max_high_current(temp_val);
2861
2862 if(C_0mA > C_400mA)
2863 {
4b9e9796
S
2864 d_val_new = (100 - d_val) - (((C_0mA-C_400mA) * (d_val)) / C_400mA);
2865/* [BUGFIX]-Add-BEGIN by TCTSZ.leo.guo, 06/25/2015, Fixed voltage calculate to report error soc. */
2866 if(d_val_new > 0) d_val = 100 - d_val_new;
2867/* [BUGFIX]-Add-BEGIN by TCTSZ.leo.guo, 06/25/2015 */
6fa3eb70
S
2868 }
2869 bm_print(BM_LOG_FULL, "[battery_meter_trans_battery_percentage] %d,%d,%d,%d,%d,%d,%d\r\n",
2870 temp_val, C_0mA, C_400mA, d_val_temp, d_val_new, d_val, g_currentfactor);
2871 //----------------------------------------------------------------------------
2872
2873 return d_val;
2874}
2875#endif
2876kal_int32 battery_meter_get_battery_percentage(void)
2877{
2878#if defined(CONFIG_POWER_EXT)
2879 return 50;
2880#else
2881
2882 if (bat_is_charger_exist() == KAL_FALSE)
2883 fg_qmax_update_for_aging_flag = 1;
2884
2885#if defined(SOC_BY_AUXADC)
2886 return auxadc_algo_run();
2887#endif
2888
2889#if defined(SOC_BY_HW_FG)
2890 if (g_auxadc_solution == 1) {
2891 return auxadc_algo_run();
2892 } else {
2893 fgauge_algo_run();
2894 return gFG_capacity_by_c; /* hw fg, //return gfg_percent_check_point; // voltage mode */
2895 }
2896#endif
2897
2898#if defined(SOC_BY_SW_FG)
2899 oam_run();
2900
2901 #ifdef CUST_CAPACITY_OCV2CV_TRANSFORM
2902 #if (OAM_D5 == 1)
2903 return (100-battery_meter_trans_battery_percentage(oam_d_5));
2904 #else
2905 return (100-battery_meter_trans_battery_percentage(oam_d_2));
2906 #endif
2907 #else
2908 #if (OAM_D5 == 1)
2909 return (100-oam_d_5);
2910 #else
2911 return (100-oam_d_2);
2912 #endif
2913 #endif
2914
2915#endif
2916
2917#endif
2918}
2919
2920
2921kal_int32 battery_meter_initial(void)
2922{
2923#if defined(CONFIG_POWER_EXT)
2924 return 0;
2925#else
2926 static kal_bool meter_initilized = KAL_FALSE;
2927
2928 mutex_lock(&FGADC_mutex);
2929 if (meter_initilized == KAL_FALSE) {
2930#ifdef MTK_MULTI_BAT_PROFILE_SUPPORT
2931 fgauge_get_profile_id();
2932#endif
2933
2934#if defined(SOC_BY_AUXADC)
2935 g_auxadc_solution = 1;
2936 table_init();
2937 bm_print(BM_LOG_CRTI, "[battery_meter_initial] SOC_BY_AUXADC done\n");
2938#endif
2939
2940#if defined(SOC_BY_HW_FG)
2941 fgauge_initialization();
2942 fgauge_algo_run_init();
2943 bm_print(BM_LOG_CRTI, "[battery_meter_initial] SOC_BY_HW_FG done\n");
2944#endif
2945
2946#if defined(SOC_BY_SW_FG)
2947 g_auxadc_solution = 1;
2948 table_init();
2949 oam_init();
2950 bm_print(BM_LOG_CRTI, "[battery_meter_initial] SOC_BY_SW_FG done\n");
2951#endif
2952
2953 meter_initilized = KAL_TRUE;
2954 }
2955 mutex_unlock(&FGADC_mutex);
2956 return 0;
2957#endif
2958}
2959
2960void reset_parameter_car(void)
2961{
2962#if defined(SOC_BY_HW_FG)
2963 int ret = 0;
2964 ret = battery_meter_ctrl(BATTERY_METER_CMD_HW_RESET, NULL);
2965 gFG_columb = 0;
2966
2967#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
2968 gFG_pre_columb_count = 0;
2969#endif
2970
2971#ifdef MTK_ENABLE_AGING_ALGORITHM
2972 aging_ocv_1 = 0;
2973 aging_ocv_2 = 0;
2974#ifdef MD_SLEEP_CURRENT_CHECK
2975 columb_before_sleep = 0x123456;
2976#endif
2977#endif
2978
2979#endif
2980
2981#if defined(SOC_BY_SW_FG)
2982 oam_car_1 = 0;
2983 oam_car_2 = 0;
2984 gFG_columb = 0;
2985#endif
2986}
2987
2988void reset_parameter_dod_change(void)
2989{
2990#if defined(SOC_BY_HW_FG)
2991 bm_print(BM_LOG_CRTI, "[FGADC] Update DOD0(%d) by %d \r\n", gFG_DOD0, gFG_DOD1);
2992 gFG_DOD0 = gFG_DOD1;
2993#endif
2994
2995#if defined(SOC_BY_SW_FG)
2996 bm_print(BM_LOG_CRTI, "[FGADC] Update oam_d0(%d) by %d \r\n", oam_d0, oam_d_5);
2997 oam_d0 = oam_d_5;
2998 gFG_DOD0 = oam_d0;
2999 oam_d_1 = oam_d_5;
3000 oam_d_2 = oam_d_5;
3001 oam_d_3 = oam_d_5;
3002 oam_d_4 = oam_d_5;
3003#endif
3004}
3005
3006void reset_parameter_dod_full(kal_uint32 ui_percentage)
3007{
3008#if defined(SOC_BY_HW_FG)
3009 bm_print(BM_LOG_CRTI, "[battery_meter_reset]1 DOD0=%d,DOD1=%d,ui=%d\n", gFG_DOD0, gFG_DOD1,
3010 ui_percentage);
3011 gFG_DOD0 = 100 - ui_percentage;
3012 gFG_DOD1 = gFG_DOD0;
3013 bm_print(BM_LOG_CRTI, "[battery_meter_reset]2 DOD0=%d,DOD1=%d,ui=%d\n", gFG_DOD0, gFG_DOD1,
3014 ui_percentage);
3015#endif
3016
3017#if defined(SOC_BY_SW_FG)
3018 bm_print(BM_LOG_CRTI, "[battery_meter_reset]1 oam_d0=%d,oam_d_5=%d,ui=%d\n", oam_d0,
3019 oam_d_5, ui_percentage);
3020 oam_d0 = 100 - ui_percentage;
3021 gFG_DOD0 = oam_d0;
3022 gFG_DOD1 = oam_d0;
3023 oam_d_1 = oam_d0;
3024 oam_d_2 = oam_d0;
3025 oam_d_3 = oam_d0;
3026 oam_d_4 = oam_d0;
3027 oam_d_5 = oam_d0;
3028 bm_print(BM_LOG_CRTI, "[battery_meter_reset]2 oam_d0=%d,oam_d_5=%d,ui=%d\n", oam_d0,
3029 oam_d_5, ui_percentage);
3030#endif
3031}
3032
3033kal_int32 battery_meter_reset(void)
3034{
3035#if defined(CONFIG_POWER_EXT)
3036 return 0;
3037#else
3038 kal_uint32 ui_percentage = bat_get_ui_percentage();
3039
3040#ifdef CUST_CAPACITY_OCV2CV_TRANSFORM
3041 if (KAL_FALSE == g_USE_UI_SOC) {
3042 /*use battery_soc*/
3043 ui_percentage = battery_meter_get_battery_soc();
3044 g_USE_UI_SOC = KAL_TRUE;
3045 bm_print(BM_LOG_FULL, "[CUST_CAPACITY_OCV2CV_TRANSFORM]Use Battery SOC: %d\n", ui_percentage);
3046 }
3047#endif
3048 if (bat_is_charging_full() == KAL_TRUE) /* charge full */
3049 {
3050 if (fg_qmax_update_for_aging_flag == 1) {
3051 fg_qmax_update_for_aging();
3052 fg_qmax_update_for_aging_flag = 0;
3053 }
3054 }
3055
3056 reset_parameter_car();
3057 reset_parameter_dod_full(ui_percentage);
3058
3059 return 0;
3060#endif
3061}
3062
3063kal_int32 battery_meter_sync(kal_int32 bat_i_sense_offset)
3064{
3065#if defined(CONFIG_POWER_EXT)
3066 return 0;
3067#else
3068 g_I_SENSE_offset = bat_i_sense_offset;
3069 return 0;
3070#endif
3071}
3072
3073kal_int32 battery_meter_get_battery_zcv(void)
3074{
3075#if defined(CONFIG_POWER_EXT)
3076 return 3987;
3077#else
3078 return gFG_voltage;
3079#endif
3080}
3081
3082kal_int32 battery_meter_get_battery_nPercent_zcv(void)
3083{
3084#if defined(CONFIG_POWER_EXT)
3085 return 3700;
3086#else
3087 return gFG_15_vlot; /* 15% zcv, 15% can be customized by 100-g_tracking_point */
3088#endif
3089}
3090
3091kal_int32 battery_meter_get_battery_nPercent_UI_SOC(void)
3092{
3093#if defined(CONFIG_POWER_EXT)
3094 return 15;
3095#else
3096 return g_tracking_point; /* tracking point */
3097#endif
3098}
3099
3100kal_int32 battery_meter_get_tempR(kal_int32 dwVolt)
3101{
3102#if defined(CONFIG_POWER_EXT)
3103 return 0;
3104#else
3105 int TRes;
3106
3107 TRes = (RBAT_PULL_UP_R * dwVolt) / (RBAT_PULL_UP_VOLT - dwVolt);
3108
3109 return TRes;
3110#endif
3111}
3112
3113kal_int32 battery_meter_get_tempV(void)
3114{
3115#if defined(CONFIG_POWER_EXT)
3116 return 0;
3117#else
3118 int ret = 0;
3119 int val = 0;
3120
3121 val = 1; /* set avg times */
3122 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_BAT_TEMP, &val);
3123 return val;
3124#endif
3125}
3126
3127kal_int32 battery_meter_get_VSense(void)
3128{
3129#if defined(CONFIG_POWER_EXT)
3130 return 0;
3131#else
3132 int ret = 0;
3133 int val = 0;
3134
3135 val = 1; /* set avg times */
3136 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_ADC_V_I_SENSE, &val);
3137 return val;
3138#endif
3139}
3140
3141/* ============================================================ // */
3142static ssize_t fgadc_log_write(struct file *filp, const char __user *buff,
3143 size_t len, loff_t *data)
3144{
4b9e9796
S
3145
3146 char proc_fgadc_data;
3147
3148 if ((len <= 0) || copy_from_user(&proc_fgadc_data, buff, 1)) {
6fa3eb70
S
3149 bm_print(BM_LOG_CRTI, "fgadc_log_write error.\n");
3150 return -EFAULT;
3151 }
3152
4b9e9796 3153 if (proc_fgadc_data == '1') {
6fa3eb70
S
3154 bm_print(BM_LOG_CRTI, "enable FGADC driver log system\n");
3155 Enable_FGADC_LOG = 1;
4b9e9796 3156 } else if (proc_fgadc_data == '2') {
6fa3eb70
S
3157 bm_print(BM_LOG_CRTI, "enable FGADC driver log system:2\n");
3158 Enable_FGADC_LOG = 2;
3159 } else {
3160 bm_print(BM_LOG_CRTI, "Disable FGADC driver log system\n");
3161 Enable_FGADC_LOG = 0;
3162 }
3163
3164 return len;
3165}
3166
3167static const struct file_operations fgadc_proc_fops = {
3168 .write = fgadc_log_write,
3169};
3170
3171int init_proc_log_fg(void)
3172{
3173 int ret = 0;
3174
3175#if 1
3176 proc_create("fgadc_log", 0644, NULL, &fgadc_proc_fops);
3177 bm_print(BM_LOG_CRTI, "proc_create fgadc_proc_fops\n");
3178#else
3179 proc_entry_fgadc = create_proc_entry("fgadc_log", 0644, NULL);
3180
3181 if (proc_entry_fgadc == NULL) {
3182 ret = -ENOMEM;
3183 bm_print(BM_LOG_CRTI, "init_proc_log_fg: Couldn't create proc entry\n");
3184 } else {
3185 proc_entry_fgadc->write_proc = fgadc_log_write;
3186 bm_print(BM_LOG_CRTI, "init_proc_log_fg loaded.\n");
3187 }
3188#endif
3189
3190 return ret;
3191}
3192
3193#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
3194
3195/* ============================================================ // */
3196
3197#ifdef CUSTOM_BATTERY_CYCLE_AGING_DATA
3198
3199kal_int32 get_battery_aging_factor(kal_int32 cycle)
3200{
3201 kal_int32 i, f1, f2, c1, c2;
3202 kal_int32 saddles;
3203
3204 saddles = sizeof(battery_aging_table) / sizeof(BATTERY_CYCLE_STRUC);
3205
3206 for (i = 0; i < saddles; i++) {
3207 if (battery_aging_table[i].cycle == cycle) {
3208 return battery_aging_table[i].aging_factor;
3209 }
3210
3211 if (battery_aging_table[i].cycle > cycle) {
3212 if (i == 0) {
3213 return 100;
3214 }
3215
3216 if (battery_aging_table[i].aging_factor >
3217 battery_aging_table[i - 1].aging_factor) {
3218 f1 = battery_aging_table[i].aging_factor;
3219 f2 = battery_aging_table[i - 1].aging_factor;
3220 c1 = battery_aging_table[i].cycle;
3221 c2 = battery_aging_table[i - 1].cycle;
3222 return (f2 + ((cycle - c2) * (f1 - f2)) / (c1 - c2));
3223 } else {
3224 f1 = battery_aging_table[i - 1].aging_factor;
3225 f2 = battery_aging_table[i].aging_factor;
3226 c1 = battery_aging_table[i].cycle;
3227 c2 = battery_aging_table[i - 1].cycle;
3228 return (f2 + ((cycle - c2) * (f1 - f2)) / (c1 - c2));
3229 }
3230 }
3231 }
3232
3233 return battery_aging_table[saddles - 1].aging_factor;
3234}
3235
3236#endif
3237
3238static ssize_t show_FG_Battery_Cycle(struct device *dev, struct device_attribute *attr, char *buf)
3239{
3240 bm_print(BM_LOG_CRTI, "[FG] gFG_battery_cycle : %d\n", gFG_battery_cycle);
3241 return sprintf(buf, "%d\n", gFG_battery_cycle);
3242}
3243
3244static ssize_t store_FG_Battery_Cycle(struct device *dev, struct device_attribute *attr,
3245 const char *buf, size_t size)
3246{
3247 kal_int32 cycle;
3248
3249#ifdef CUSTOM_BATTERY_CYCLE_AGING_DATA
3250 kal_int32 aging_capacity;
3251 kal_int32 factor;
3252#endif
3253
3254 if (1 == sscanf(buf, "%d", &cycle)) {
3255 bm_print(BM_LOG_CRTI, "[FG] update battery cycle count: %d\n", cycle);
3256 gFG_battery_cycle = cycle;
3257
3258#ifdef CUSTOM_BATTERY_CYCLE_AGING_DATA
3259 /* perform cycle aging calculation */
3260
3261 factor = get_battery_aging_factor(gFG_battery_cycle);
3262 if (factor > 0 && factor < 100) {
3263 bm_print(BM_LOG_CRTI, "[FG] cycle count to aging factor %d\n", factor);
3264 aging_capacity = gFG_BATT_CAPACITY * factor / 100;
3265 if (aging_capacity < gFG_BATT_CAPACITY_aging) {
3266 bm_print(BM_LOG_CRTI, "[FG] update gFG_BATT_CAPACITY_aging to %d\n",
3267 aging_capacity);
3268 gFG_BATT_CAPACITY_aging = aging_capacity;
3269 }
3270 }
3271#endif
3272 } else {
3273 bm_print(BM_LOG_CRTI, "[FG] format error!\n");
3274 }
3275 return size;
3276}
3277
3278static DEVICE_ATTR(FG_Battery_Cycle, 0664, show_FG_Battery_Cycle, store_FG_Battery_Cycle);
3279
3280/* ------------------------------------------------------------------------------------------- */
3281
3282static ssize_t show_FG_Max_Battery_Voltage(struct device *dev, struct device_attribute *attr,
3283 char *buf)
3284{
3285 bm_print(BM_LOG_CRTI, "[FG] gFG_max_voltage : %d\n", gFG_max_voltage);
3286 return sprintf(buf, "%d\n", gFG_max_voltage);
3287}
3288
3289static ssize_t store_FG_Max_Battery_Voltage(struct device *dev, struct device_attribute *attr,
3290 const char *buf, size_t size)
3291{
3292 kal_int32 voltage;
3293 if (1 == sscanf(buf, "%d", &voltage)) {
3294 if (voltage > gFG_max_voltage) {
3295 bm_print(BM_LOG_CRTI, "[FG] update battery max voltage: %d\n", voltage);
3296 gFG_max_voltage = voltage;
3297 }
3298 } else {
3299 bm_print(BM_LOG_CRTI, "[FG] format error!\n");
3300 }
3301 return size;
3302}
3303
3304static DEVICE_ATTR(FG_Max_Battery_Voltage, 0664, show_FG_Max_Battery_Voltage,
3305 store_FG_Max_Battery_Voltage);
3306
3307/* ------------------------------------------------------------------------------------------- */
3308
3309static ssize_t show_FG_Min_Battery_Voltage(struct device *dev, struct device_attribute *attr,
3310 char *buf)
3311{
3312 bm_print(BM_LOG_CRTI, "[FG] gFG_min_voltage : %d\n", gFG_min_voltage);
3313 return sprintf(buf, "%d\n", gFG_min_voltage);
3314}
3315
3316static ssize_t store_FG_Min_Battery_Voltage(struct device *dev, struct device_attribute *attr,
3317 const char *buf, size_t size)
3318{
3319 kal_int32 voltage;
3320 if (1 == sscanf(buf, "%d", &voltage)) {
3321 if (voltage < gFG_min_voltage) {
3322 bm_print(BM_LOG_CRTI, "[FG] update battery min voltage: %d\n", voltage);
3323 gFG_min_voltage = voltage;
3324 }
3325 } else {
3326 bm_print(BM_LOG_CRTI, "[FG] format error!\n");
3327 }
3328 return size;
3329}
3330
3331static DEVICE_ATTR(FG_Min_Battery_Voltage, 0664, show_FG_Min_Battery_Voltage,
3332 store_FG_Min_Battery_Voltage);
3333
3334/* ------------------------------------------------------------------------------------------- */
3335
3336static ssize_t show_FG_Max_Battery_Current(struct device *dev, struct device_attribute *attr,
3337 char *buf)
3338{
3339 bm_print(BM_LOG_CRTI, "[FG] gFG_max_current : %d\n", gFG_max_current);
3340 return sprintf(buf, "%d\n", gFG_max_current);
3341}
3342
3343static ssize_t store_FG_Max_Battery_Current(struct device *dev, struct device_attribute *attr,
3344 const char *buf, size_t size)
3345{
3346 kal_int32 bat_current;
3347 if (1 == sscanf(buf, "%d", &bat_current)) {
3348 if (bat_current > gFG_max_current) {
3349 bm_print(BM_LOG_CRTI, "[FG] update battery max current: %d\n", bat_current);
3350 gFG_max_current = bat_current;
3351 }
3352 } else {
3353 bm_print(BM_LOG_CRTI, "[FG] format error!\n");
3354 }
3355 return size;
3356}
3357
3358static DEVICE_ATTR(FG_Max_Battery_Current, 0664, show_FG_Max_Battery_Current,
3359 store_FG_Max_Battery_Current);
3360
3361/* ------------------------------------------------------------------------------------------- */
3362
3363static ssize_t show_FG_Min_Battery_Current(struct device *dev, struct device_attribute *attr,
3364 char *buf)
3365{
3366 bm_print(BM_LOG_CRTI, "[FG] gFG_min_current : %d\n", gFG_min_current);
3367 return sprintf(buf, "%d\n", gFG_min_current);
3368}
3369
3370static ssize_t store_FG_Min_Battery_Current(struct device *dev, struct device_attribute *attr,
3371 const char *buf, size_t size)
3372{
3373 kal_int32 bat_current;
3374 if (1 == sscanf(buf, "%d", &bat_current)) {
3375 if (bat_current < gFG_min_current) {
3376 bm_print(BM_LOG_CRTI, "[FG] update battery min current: %d\n", bat_current);
3377 gFG_min_current = bat_current;
3378 }
3379 } else {
3380 bm_print(BM_LOG_CRTI, "[FG] format error!\n");
3381 }
3382 return size;
3383}
3384
3385static DEVICE_ATTR(FG_Min_Battery_Current, 0664, show_FG_Min_Battery_Current,
3386 store_FG_Min_Battery_Current);
3387
3388/* ------------------------------------------------------------------------------------------- */
3389
3390static ssize_t show_FG_Max_Battery_Temperature(struct device *dev, struct device_attribute *attr,
3391 char *buf)
3392{
3393 bm_print(BM_LOG_CRTI, "[FG] gFG_max_temperature : %d\n", gFG_max_temperature);
3394 return sprintf(buf, "%d\n", gFG_max_temperature);
3395}
3396
3397static ssize_t store_FG_Max_Battery_Temperature(struct device *dev, struct device_attribute *attr,
3398 const char *buf, size_t size)
3399{
3400 kal_int32 temp;
3401 if (1 == sscanf(buf, "%d", &temp)) {
3402 if (temp > gFG_max_temperature) {
3403 bm_print(BM_LOG_CRTI, "[FG] update battery max temp: %d\n", temp);
3404 gFG_max_temperature = temp;
3405 }
3406 } else {
3407 bm_print(BM_LOG_CRTI, "[FG] format error!\n");
3408 }
3409 return size;
3410}
3411
3412static DEVICE_ATTR(FG_Max_Battery_Temperature, 0664, show_FG_Max_Battery_Temperature,
3413 store_FG_Max_Battery_Temperature);
3414
3415/* ------------------------------------------------------------------------------------------- */
3416
3417static ssize_t show_FG_Min_Battery_Temperature(struct device *dev, struct device_attribute *attr,
3418 char *buf)
3419{
3420 bm_print(BM_LOG_CRTI, "[FG] gFG_min_temperature : %d\n", gFG_min_temperature);
3421 return sprintf(buf, "%d\n", gFG_min_temperature);
3422}
3423
3424static ssize_t store_FG_Min_Battery_Temperature(struct device *dev, struct device_attribute *attr,
3425 const char *buf, size_t size)
3426{
3427 kal_int32 temp;
3428 if (1 == sscanf(buf, "%d", &temp)) {
3429 if (temp < gFG_min_temperature) {
3430 bm_print(BM_LOG_CRTI, "[FG] update battery min temp: %d\n", temp);
3431 gFG_min_temperature = temp;
3432 }
3433 } else {
3434 bm_print(BM_LOG_CRTI, "[FG] format error!\n");
3435 }
3436 return size;
3437}
3438
3439static DEVICE_ATTR(FG_Min_Battery_Temperature, 0664, show_FG_Min_Battery_Temperature,
3440 store_FG_Min_Battery_Temperature);
3441
3442/* ------------------------------------------------------------------------------------------- */
3443
3444static ssize_t show_FG_Aging_Factor(struct device *dev, struct device_attribute *attr, char *buf)
3445{
3446 bm_print(BM_LOG_CRTI, "[FG] gFG_aging_factor : %d\n", gFG_aging_factor);
3447 return sprintf(buf, "%d\n", gFG_aging_factor);
3448}
3449
3450static ssize_t store_FG_Aging_Factor(struct device *dev, struct device_attribute *attr,
3451 const char *buf, size_t size)
3452{
3453 kal_int32 factor;
3454 kal_int32 aging_capacity;
3455
3456 if (1 == sscanf(buf, "%d", &factor)) {
3457 if (factor <= 100 && factor >= 0) {
3458 bm_print(BM_LOG_CRTI,
3459 "[FG] update battery aging factor: old(%d), new(%d)\n",
3460 gFG_aging_factor, factor);
3461
3462 gFG_aging_factor = factor;
3463
3464 if (gFG_aging_factor != 100) {
3465 aging_capacity = gFG_BATT_CAPACITY * gFG_aging_factor / 100;
3466 if (aging_capacity < gFG_BATT_CAPACITY_aging) {
3467 bm_print(BM_LOG_CRTI,
3468 "[FG] update gFG_BATT_CAPACITY_aging to %d\n",
3469 aging_capacity);
3470 gFG_BATT_CAPACITY_aging = aging_capacity;
3471 }
3472 }
3473 }
3474 } else {
3475 bm_print(BM_LOG_CRTI, "[FG] format error!\n");
3476 }
3477
3478 return size;
3479}
3480
3481static DEVICE_ATTR(FG_Aging_Factor, 0664, show_FG_Aging_Factor, store_FG_Aging_Factor);
3482
3483/* ------------------------------------------------------------------------------------------- */
3484
3485#endif
3486
3487/* ============================================================ // */
3488static ssize_t show_FG_Current(struct device *dev, struct device_attribute *attr, char *buf)
3489{
3490 kal_int32 ret = 0;
3491 kal_int32 fg_current_inout_battery = 0;
3492 kal_int32 val = 0;
3493 kal_bool is_charging = 0;
3494
3495 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT, &val);
3496 ret = battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CURRENT_SIGN, &is_charging);
3497
3498 if (is_charging == KAL_TRUE) {
3499 fg_current_inout_battery = 0 - val;
3500 } else {
3501 fg_current_inout_battery = val;
3502 }
3503
3504 bm_print(BM_LOG_CRTI, "[FG] gFG_current_inout_battery : %d\n", fg_current_inout_battery);
3505 return sprintf(buf, "%d\n", fg_current_inout_battery);
3506}
3507
3508static ssize_t store_FG_Current(struct device *dev, struct device_attribute *attr, const char *buf,
3509 size_t size)
3510{
3511 return size;
3512}
3513
3514static DEVICE_ATTR(FG_Current, 0664, show_FG_Current, store_FG_Current);
3515
3516/* ============================================================ // */
3517static ssize_t show_FG_g_fg_dbg_bat_volt(struct device *dev, struct device_attribute *attr,
3518 char *buf)
3519{
3520 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_bat_volt : %d\n", g_fg_dbg_bat_volt);
3521 return sprintf(buf, "%d\n", g_fg_dbg_bat_volt);
3522}
3523
3524static ssize_t store_FG_g_fg_dbg_bat_volt(struct device *dev, struct device_attribute *attr,
3525 const char *buf, size_t size)
3526{
3527 return size;
3528}
3529
3530static DEVICE_ATTR(FG_g_fg_dbg_bat_volt, 0664, show_FG_g_fg_dbg_bat_volt,
3531 store_FG_g_fg_dbg_bat_volt);
3532/* ------------------------------------------------------------------------------------------- */
3533static ssize_t show_FG_g_fg_dbg_bat_current(struct device *dev, struct device_attribute *attr,
3534 char *buf)
3535{
3536 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_bat_current : %d\n", g_fg_dbg_bat_current);
3537 return sprintf(buf, "%d\n", g_fg_dbg_bat_current);
3538}
3539
3540static ssize_t store_FG_g_fg_dbg_bat_current(struct device *dev, struct device_attribute *attr,
3541 const char *buf, size_t size)
3542{
3543 return size;
3544}
3545
3546static DEVICE_ATTR(FG_g_fg_dbg_bat_current, 0664, show_FG_g_fg_dbg_bat_current,
3547 store_FG_g_fg_dbg_bat_current);
3548/* ------------------------------------------------------------------------------------------- */
3549static ssize_t show_FG_g_fg_dbg_bat_zcv(struct device *dev, struct device_attribute *attr,
3550 char *buf)
3551{
3552 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_bat_zcv : %d\n", g_fg_dbg_bat_zcv);
3553 return sprintf(buf, "%d\n", g_fg_dbg_bat_zcv);
3554}
3555
3556static ssize_t store_FG_g_fg_dbg_bat_zcv(struct device *dev, struct device_attribute *attr,
3557 const char *buf, size_t size)
3558{
3559 return size;
3560}
3561
3562static DEVICE_ATTR(FG_g_fg_dbg_bat_zcv, 0664, show_FG_g_fg_dbg_bat_zcv, store_FG_g_fg_dbg_bat_zcv);
3563/* ------------------------------------------------------------------------------------------- */
3564static ssize_t show_FG_g_fg_dbg_bat_temp(struct device *dev, struct device_attribute *attr,
3565 char *buf)
3566{
3567 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_bat_temp : %d\n", g_fg_dbg_bat_temp);
3568 return sprintf(buf, "%d\n", g_fg_dbg_bat_temp);
3569}
3570
3571static ssize_t store_FG_g_fg_dbg_bat_temp(struct device *dev, struct device_attribute *attr,
3572 const char *buf, size_t size)
3573{
3574 return size;
3575}
3576
3577static DEVICE_ATTR(FG_g_fg_dbg_bat_temp, 0664, show_FG_g_fg_dbg_bat_temp,
3578 store_FG_g_fg_dbg_bat_temp);
3579/* ------------------------------------------------------------------------------------------- */
3580static ssize_t show_FG_g_fg_dbg_bat_r(struct device *dev, struct device_attribute *attr, char *buf)
3581{
3582 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_bat_r : %d\n", g_fg_dbg_bat_r);
3583 return sprintf(buf, "%d\n", g_fg_dbg_bat_r);
3584}
3585
3586static ssize_t store_FG_g_fg_dbg_bat_r(struct device *dev, struct device_attribute *attr,
3587 const char *buf, size_t size)
3588{
3589 return size;
3590}
3591
3592static DEVICE_ATTR(FG_g_fg_dbg_bat_r, 0664, show_FG_g_fg_dbg_bat_r, store_FG_g_fg_dbg_bat_r);
3593/* ------------------------------------------------------------------------------------------- */
3594static ssize_t show_FG_g_fg_dbg_bat_car(struct device *dev, struct device_attribute *attr,
3595 char *buf)
3596{
3597 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_bat_car : %d\n", g_fg_dbg_bat_car);
3598 return sprintf(buf, "%d\n", g_fg_dbg_bat_car);
3599}
3600
3601static ssize_t store_FG_g_fg_dbg_bat_car(struct device *dev, struct device_attribute *attr,
3602 const char *buf, size_t size)
3603{
3604 return size;
3605}
3606
3607static DEVICE_ATTR(FG_g_fg_dbg_bat_car, 0664, show_FG_g_fg_dbg_bat_car, store_FG_g_fg_dbg_bat_car);
3608/* ------------------------------------------------------------------------------------------- */
3609static ssize_t show_FG_g_fg_dbg_bat_qmax(struct device *dev, struct device_attribute *attr,
3610 char *buf)
3611{
3612 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_bat_qmax : %d\n", g_fg_dbg_bat_qmax);
3613 return sprintf(buf, "%d\n", g_fg_dbg_bat_qmax);
3614}
3615
3616static ssize_t store_FG_g_fg_dbg_bat_qmax(struct device *dev, struct device_attribute *attr,
3617 const char *buf, size_t size)
3618{
3619 return size;
3620}
3621
3622static DEVICE_ATTR(FG_g_fg_dbg_bat_qmax, 0664, show_FG_g_fg_dbg_bat_qmax,
3623 store_FG_g_fg_dbg_bat_qmax);
3624/* ------------------------------------------------------------------------------------------- */
3625static ssize_t show_FG_g_fg_dbg_d0(struct device *dev, struct device_attribute *attr, char *buf)
3626{
3627 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_d0 : %d\n", g_fg_dbg_d0);
3628 return sprintf(buf, "%d\n", g_fg_dbg_d0);
3629}
3630
3631static ssize_t store_FG_g_fg_dbg_d0(struct device *dev, struct device_attribute *attr,
3632 const char *buf, size_t size)
3633{
3634 return size;
3635}
3636
3637static DEVICE_ATTR(FG_g_fg_dbg_d0, 0664, show_FG_g_fg_dbg_d0, store_FG_g_fg_dbg_d0);
3638/* ------------------------------------------------------------------------------------------- */
3639static ssize_t show_FG_g_fg_dbg_d1(struct device *dev, struct device_attribute *attr, char *buf)
3640{
3641 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_d1 : %d\n", g_fg_dbg_d1);
3642 return sprintf(buf, "%d\n", g_fg_dbg_d1);
3643}
3644
3645static ssize_t store_FG_g_fg_dbg_d1(struct device *dev, struct device_attribute *attr,
3646 const char *buf, size_t size)
3647{
3648 return size;
3649}
3650
3651static DEVICE_ATTR(FG_g_fg_dbg_d1, 0664, show_FG_g_fg_dbg_d1, store_FG_g_fg_dbg_d1);
3652/* ------------------------------------------------------------------------------------------- */
3653static ssize_t show_FG_g_fg_dbg_percentage(struct device *dev, struct device_attribute *attr,
3654 char *buf)
3655{
3656 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_percentage : %d\n", g_fg_dbg_percentage);
3657 return sprintf(buf, "%d\n", g_fg_dbg_percentage);
3658}
3659
3660static ssize_t store_FG_g_fg_dbg_percentage(struct device *dev, struct device_attribute *attr,
3661 const char *buf, size_t size)
3662{
3663 return size;
3664}
3665
3666static DEVICE_ATTR(FG_g_fg_dbg_percentage, 0664, show_FG_g_fg_dbg_percentage,
3667 store_FG_g_fg_dbg_percentage);
3668/* ------------------------------------------------------------------------------------------- */
3669static ssize_t show_FG_g_fg_dbg_percentage_fg(struct device *dev, struct device_attribute *attr,
3670 char *buf)
3671{
3672 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_percentage_fg : %d\n", g_fg_dbg_percentage_fg);
3673 return sprintf(buf, "%d\n", g_fg_dbg_percentage_fg);
3674}
3675
3676static ssize_t store_FG_g_fg_dbg_percentage_fg(struct device *dev, struct device_attribute *attr,
3677 const char *buf, size_t size)
3678{
3679 return size;
3680}
3681
3682static DEVICE_ATTR(FG_g_fg_dbg_percentage_fg, 0664, show_FG_g_fg_dbg_percentage_fg,
3683 store_FG_g_fg_dbg_percentage_fg);
3684/* ------------------------------------------------------------------------------------------- */
3685static ssize_t show_FG_g_fg_dbg_percentage_voltmode(struct device *dev,
3686 struct device_attribute *attr, char *buf)
3687{
3688 bm_print(BM_LOG_CRTI, "[FG] g_fg_dbg_percentage_voltmode : %d\n",
3689 g_fg_dbg_percentage_voltmode);
3690 return sprintf(buf, "%d\n", g_fg_dbg_percentage_voltmode);
3691}
3692
3693static ssize_t store_FG_g_fg_dbg_percentage_voltmode(struct device *dev,
3694 struct device_attribute *attr, const char *buf,
3695 size_t size)
3696{
3697 return size;
3698}
3699
3700static DEVICE_ATTR(FG_g_fg_dbg_percentage_voltmode, 0664, show_FG_g_fg_dbg_percentage_voltmode,
3701 store_FG_g_fg_dbg_percentage_voltmode);
3702
3703/* ============================================================ // */
3704static int battery_meter_probe(struct platform_device *dev)
3705{
3706 int ret_device_file = 0;
3707 char* temp_strptr;
3708 battery_meter_ctrl = bm_ctrl_cmd;
3709
3710 bm_print(BM_LOG_CRTI, "[battery_meter_probe] probe\n");
3711 /* select battery meter control method */
3712 battery_meter_ctrl = bm_ctrl_cmd;
3713#if defined (CONFIG_MTK_KERNEL_POWER_OFF_CHARGING)
3714 if (g_boot_mode == LOW_POWER_OFF_CHARGING_BOOT || g_boot_mode == KERNEL_POWER_OFF_CHARGING_BOOT) {
3715 temp_strptr = kzalloc(strlen(saved_command_line)+strlen(" androidboot.mode=charger")+1, GFP_KERNEL);
3716 strcpy(temp_strptr, saved_command_line);
3717 strcat(temp_strptr, " androidboot.mode=charger");
3718 saved_command_line = temp_strptr;
3719 }
3720#endif
3721 /* LOG System Set */
3722 init_proc_log_fg();
3723
3724 /* last_oam_run_time = rtc_read_hw_time(); */
3725 getrawmonotonic(&last_oam_run_time);
3726 /* Create File For FG UI DEBUG */
3727 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_Current);
3728 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_bat_volt);
3729 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_bat_current);
3730 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_bat_zcv);
3731 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_bat_temp);
3732 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_bat_r);
3733 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_bat_car);
3734 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_bat_qmax);
3735 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_d0);
3736 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_d1);
3737 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_percentage);
3738 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_percentage_fg);
3739 ret_device_file =
3740 device_create_file(&(dev->dev), &dev_attr_FG_g_fg_dbg_percentage_voltmode);
3741
3742#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
3743 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_Battery_Cycle);
3744 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_Aging_Factor);
3745 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_Max_Battery_Voltage);
3746 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_Min_Battery_Voltage);
3747 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_Max_Battery_Current);
3748 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_Min_Battery_Current);
3749 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_Max_Battery_Temperature);
3750 ret_device_file = device_create_file(&(dev->dev), &dev_attr_FG_Min_Battery_Temperature);
3751#endif
3752
3753 return 0;
3754}
3755
3756static int battery_meter_remove(struct platform_device *dev)
3757{
3758 bm_print(BM_LOG_CRTI, "[battery_meter_remove]\n");
3759 return 0;
3760}
3761
3762static void battery_meter_shutdown(struct platform_device *dev)
3763{
3764 bm_print(BM_LOG_CRTI, "[battery_meter_shutdown]\n");
3765}
3766
3767static int battery_meter_suspend(struct platform_device *dev, pm_message_t state)
3768{
3769#if defined(CONFIG_POWER_EXT)
3770
3771#elif defined(SOC_BY_SW_FG) || defined(SOC_BY_HW_FG)
3772 struct timespec xts, tom;
3773#endif
3774 /* -- hibernation path */
3775 if (state.event == PM_EVENT_FREEZE) {
3776 pr_warn("[%s] %p:%p\n", __func__, battery_meter_ctrl, &bm_ctrl_cmd);
3777 battery_meter_ctrl = bm_ctrl_cmd;
3778 }
3779 /* -- end of hibernation path */
3780#if defined(CONFIG_POWER_EXT)
3781
3782#elif defined(SOC_BY_SW_FG) || defined(SOC_BY_HW_FG)
3783 {
3784#ifdef MTK_POWER_EXT_DETECT
3785 if (KAL_TRUE == bat_is_ext_power())
3786 return 0;
3787#endif
3788
3789 /*[BUGFIX]-Add-BEGIN by TCTSZ.pingao.yang, 4/15/2015, pr-975290, add standby current */
3790 #if 0
3791 get_xtime_and_monotonic_and_sleep_offset(&xts_before_sleep, &tom, &g_rtc_time_before_sleep);
3792 if (_g_bat_sleep_total_time < g_spm_timer) {
3793 return 0;
3794 }
3795 _g_bat_sleep_total_time = 0;
3796 #else
3797 get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &g_rtc_time_before_sleep);
3798 before_sleep_time = rtc_read_hw_time();
3799 #endif
3800 /*[BUGFIX]-Add-END by TCTSZ.pingao.yang */
3801
3802 battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &g_hw_ocv_before_sleep);
3803 }
3804#endif
3805 bm_print(BM_LOG_CRTI, "[battery_meter_suspend]\n");
3806 return 0;
3807}
3808
3809#ifdef MTK_ENABLE_AGING_ALGORITHM
3810static void battery_aging_check(void)
3811{
3812 kal_int32 hw_ocv_after_sleep;
3813 struct timespec xts, tom, sleeptime;
3814 kal_int32 vbat;
3815 kal_int32 qmax_aging = 0;
3816 kal_int32 dod_gap = 10;
3817 kal_int32 columb_after_sleep = 0;
3818#if defined (MD_SLEEP_CURRENT_CHECK)
3819 kal_int32 DOD_hwocv;
3820 kal_int32 DOD_now;
3821 kal_int32 suspend_current = 0;
3822#endif
3823
3824 battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &hw_ocv_after_sleep);
3825 vbat = battery_meter_get_battery_voltage(KAL_TRUE);
3826 bm_print(BM_LOG_CRTI, "@@@ HW_OCV_D3=%d, HW_OCV_D1=%d, VBAT=%d\n", hw_ocv_after_sleep, g_hw_ocv_before_sleep, vbat);
3827
3828 // gauge correct
3829 battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &columb_after_sleep); //update columb counter to get DOD_now.
3830
3831 get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &sleeptime);
3832 suspend_time += abs(xts.tv_sec - xts_before_sleep.tv_sec);
3833 _g_bat_sleep_total_time += abs(xts.tv_sec - xts_before_sleep.tv_sec);
3834#if defined (MD_SLEEP_CURRENT_CHECK)
3835 bm_print(BM_LOG_CRTI, "sleeptime=(%d)s, car_be = %d, car_af = %d\n", suspend_time, columb_before_sleep, columb_after_sleep);
3836 if (columb_before_sleep == 0x123456) {
3837 columb_before_sleep = columb_after_sleep;
3838 suspend_time = 0;
3839 return;
3840 }
3841 if (hw_ocv_after_sleep != g_hw_ocv_before_sleep) {
3842 if(suspend_time > OCV_RECOVER_TIME) { //35 mins
3843 suspend_current = abs(columb_after_sleep - columb_before_sleep) * 3600 / suspend_time;
3844 bm_print(BM_LOG_CRTI, "[aging check]sleeptime = %d, HW_OCV_D3=%d, car_be = %d, car_af = %d, suspend cur = %d ", suspend_time, hw_ocv_after_sleep, columb_before_sleep, columb_after_sleep, suspend_current);
3845 if (suspend_current < 10) { //10mA
3846 columb_before_sleep = columb_after_sleep;
3847 suspend_time = 0;
3848 bm_print(BM_LOG_CRTI, "1\n");
3849 } else {
3850 columb_before_sleep = columb_after_sleep;
3851 suspend_time = 0;
3852 bm_print(BM_LOG_CRTI, "0\n");
3853 return ;
3854 }
3855 } else {
3856 return ;
3857 }
3858 } else {
3859 return ;
3860 }
3861#endif
3862 // aging
3863#if !defined (MD_SLEEP_CURRENT_CHECK)
3864 if(suspend_time > OCV_RECOVER_TIME)
3865#endif
3866 {
3867 if (aging_ocv_1 == 0) {
3868 aging_ocv_1 = hw_ocv_after_sleep;
3869 aging_car_1 = columb_after_sleep;
3870 //aging_resume_time_1 = time_after_sleep.tv_sec;
3871
3872 if (fgauge_read_d_by_v(aging_ocv_1) > DOD1_ABOVE_THRESHOLD) {
3873 aging_ocv_1 = 0;
3874 bm_print(BM_LOG_CRTI, "[aging check] reset and find next aging_ocv1 for better precision\n");
3875 }
3876 } else if (aging_ocv_2 == 0) {
3877 aging_ocv_2 = hw_ocv_after_sleep;
3878 aging_car_2 = columb_after_sleep;
3879 //aging_resume_time_2 = time_after_sleep.tv_sec;
3880
3881 if (fgauge_read_d_by_v(aging_ocv_2) < DOD2_BELOW_THRESHOLD) {
3882 aging_ocv_2 = 0;
3883 bm_print(BM_LOG_CRTI, "[aging check] reset and find next aging_ocv2 for better precision\n");
3884 }
3885 } else {
3886 aging_ocv_1 = aging_ocv_2;
3887 aging_car_1 = aging_car_2;
3888 //aging_resume_time_1 = aging_resume_time_2;
3889
3890 aging_ocv_2 = hw_ocv_after_sleep;
3891 aging_car_2 = columb_after_sleep;
3892 //aging_resume_time_2 = time_after_sleep.tv_sec;
3893 }
3894 }
3895
3896 if (aging_ocv_2 > 0) {
3897 aging_dod_1 = fgauge_read_d_by_v(aging_ocv_1);
3898 aging_dod_2 = fgauge_read_d_by_v(aging_ocv_2);
3899
3900 /* check dod region to avoid hwocv error margin */
3901 dod_gap = MIN_DOD_DIFF_THRESHOLD;
3902
3903 /* check if DOD gap bigger than setting */
3904 if(aging_dod_2 > aging_dod_1 && (aging_dod_2 - aging_dod_1) >= dod_gap) {
3905 /* do aging calculation */
3906 qmax_aging = (100*(aging_car_1 - aging_car_2))/(aging_dod_2 - aging_dod_1);
3907
3908 /* update if aging over 10%. */
3909 if (gFG_BATT_CAPACITY > qmax_aging
3910 && ((gFG_BATT_CAPACITY - qmax_aging) >
3911 (gFG_BATT_CAPACITY / (100 - MIN_AGING_FACTOR)))) {
3912 bm_print(BM_LOG_CRTI,
3913 "[aging check] before apply aging, qmax_aging(%d) qmax_now(%d) ocv1(%d) dod1(%d) car1(%d) ocv2(%d) dod2(%d) car2(%d)\n",
3914 qmax_aging, gFG_BATT_CAPACITY, aging_ocv_1,
3915 aging_dod_1, aging_car_1, aging_ocv_2, aging_dod_2,
3916 aging_car_2);
3917
3918#ifdef MTK_BATTERY_LIFETIME_DATA_SUPPORT
3919 gFG_aging_factor =
3920 ((gFG_BATT_CAPACITY -
3921 qmax_aging) * 100) / gFG_BATT_CAPACITY;
3922#endif
3923
3924 if (gFG_BATT_CAPACITY_aging > qmax_aging) {
3925 bm_print(BM_LOG_CRTI,
3926 "[aging check] new qmax_aging %d old qmax_aging %d\n",
3927 qmax_aging, gFG_BATT_CAPACITY_aging);
3928 gFG_BATT_CAPACITY_aging = qmax_aging;
3929 gFG_DOD0 = aging_dod_2;
3930 gFG_DOD1 = gFG_DOD0;
3931 reset_parameter_car();
3932 } else {
3933 bm_print(BM_LOG_CRTI,
3934 "[aging check] current qmax_aging %d is smaller than calculated qmax_aging %d\n",
3935 gFG_BATT_CAPACITY_aging, qmax_aging);
3936 }
3937 } else {
3938 aging_ocv_2 = 0;
3939 bm_print(BM_LOG_CRTI,
3940 "[aging check] show no degrade, qmax_aging(%d) qmax_now(%d) ocv1(%d) dod1(%d) car1(%d) ocv2(%d) dod2(%d) car2(%d)\n",
3941 qmax_aging, gFG_BATT_CAPACITY, aging_ocv_1,
3942 aging_dod_1, aging_car_1, aging_ocv_2, aging_dod_2,
3943 aging_car_2);
3944 bm_print(BM_LOG_CRTI,
3945 "[aging check] reset and find next aging_ocv2\n");
3946 }
3947 } else {
3948 aging_ocv_2 = 0;
3949 bm_print(BM_LOG_CRTI,
3950 "[aging check] reset and find next aging_ocv2\n");
3951 }
3952 bm_print(BM_LOG_CRTI,
3953 "[aging check] qmax_aging(%d) qmax_now(%d) ocv1(%d) dod1(%d) car1(%d) ocv2(%d) dod2(%d) car2(%d)\n",
3954 qmax_aging, gFG_BATT_CAPACITY, aging_ocv_1, aging_dod_1,
3955 aging_car_1, aging_ocv_2, aging_dod_2, aging_car_2);
3956 }
3957#if defined (MD_SLEEP_CURRENT_CHECK)
3958 /* self-discharging */
3959 if (hw_ocv_after_sleep < vbat) {
3960 bm_print(BM_LOG_CRTI, "Ignore HW_OCV : smaller than VBAT\n");
3961 } else {
3962
3963 DOD_hwocv = fgauge_read_d_by_v(hw_ocv_after_sleep);
3964
3965 battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_FG_CAR, &gFG_columb); /* update columb counter to get DOD_now. */
3966 DOD_now = 100 - fgauge_read_capacity(1);
3967
3968 if (DOD_hwocv > DOD_now
3969 && (DOD_hwocv - DOD_now > SELF_DISCHARGE_CHECK_THRESHOLD)) {
3970 gFG_DOD0 = DOD_hwocv;
3971 gFG_DOD1 = gFG_DOD0;
3972 reset_parameter_car();
3973 bm_print(BM_LOG_CRTI,
3974 "[self-discharge check] reset to HWOCV. dod_ocv(%d) dod_now(%d)\n",
3975 DOD_hwocv, DOD_now);
3976 }
3977 bm_print(BM_LOG_CRTI, "[self-discharge check] dod_ocv(%d) dod_now(%d)\n",
3978 DOD_hwocv, DOD_now);
3979 bm_print(BM_LOG_CRTI,
3980 "be_ocv=(%d), af_ocv=(%d), D0=(%d), car=(%d)\n",
3981 g_hw_ocv_before_sleep, hw_ocv_after_sleep,
3982 gFG_DOD0, gFG_columb);
3983 }
3984#endif
3985}
3986#endif
3987
3988static int battery_meter_resume(struct platform_device *dev)
3989{
3990/*[BUGFIX]-Add-BEGIN by TCTSZ.pingao.yang, 4/15/2015, pr-975290, add standby current */
3991#if 0
3992#if defined(CONFIG_POWER_EXT)
3993
3994#elif defined(SOC_BY_SW_FG) || defined(SOC_BY_HW_FG)
3995#if defined(SOC_BY_SW_FG)
3996 kal_int32 hw_ocv_after_sleep;
3997#endif
3998 struct timespec xts, tom, rtc_time_after_sleep;
3999#ifdef MTK_POWER_EXT_DETECT
4000 if (KAL_TRUE == bat_is_ext_power())
4001 return 0;
4002#endif
4003
4004 get_xtime_and_monotonic_and_sleep_offset(&xts, &tom, &rtc_time_after_sleep);
4005 _g_bat_sleep_total_time += rtc_time_after_sleep.tv_sec - g_rtc_time_before_sleep.tv_sec;
4006 battery_xlog_printk(BAT_LOG_CRTI,
4007 "[battery_meter_resume] sleep time = %d, g_spm_timer = %d\n",
4008 _g_bat_sleep_total_time, g_spm_timer);
4009
4010#if defined(SOC_BY_HW_FG)
4011#ifdef MTK_ENABLE_AGING_ALGORITHM
4012 if(bat_is_charger_exist() == KAL_FALSE)
4013 {
4014 battery_aging_check();
4015 }
4016#endif
4017#endif
4018
4019 if (_g_bat_sleep_total_time < g_spm_timer) {
4020 return 0;
4021 }
4022 bat_spm_timeout = true;
4023#if defined(SOC_BY_SW_FG)
4024 battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &hw_ocv_after_sleep);
4025 if (_g_bat_sleep_total_time > 3600) { /* 1hr */
4026 if (hw_ocv_after_sleep < g_hw_ocv_before_sleep) {
4027 oam_d0 = fgauge_read_d_by_v(hw_ocv_after_sleep);
4028 oam_v_ocv_2 = oam_v_ocv_1 = hw_ocv_after_sleep;
4029 oam_car_1 = 0;
4030 oam_car_2 = 0;
4031 } else {
4032 oam_car_1 = oam_car_1 + (40* (rtc_time_after_sleep.tv_sec - g_rtc_time_before_sleep.tv_sec)/3600); //0.1mAh
4033 oam_car_2 = oam_car_2 + (40* (rtc_time_after_sleep.tv_sec - g_rtc_time_before_sleep.tv_sec)/3600); //0.1mAh
4034 }
4035 }
4036 //FIXME
4037
4038 bm_print(BM_LOG_CRTI,
4039 "sleeptime=(%d)s, be_ocv=(%d), af_ocv=(%d), D0=(%d), car1=(%d), car2=(%d)\n",
4040 _g_bat_sleep_total_time,
4041 g_hw_ocv_before_sleep, hw_ocv_after_sleep, oam_d0, oam_car_1, oam_car_2);
4042#endif
4043#endif
4044
4045#else
4046 kal_int32 hw_ocv_after_sleep;
4047 kal_int32 sw_vbat;
4048 kal_int32 vbat_diff = 200;
4049
4050 static kal_int32 suspend_oam_time = 0;
4051 kal_int32 oam_car_delta = 0;
4052
4053 after_sleep_time = rtc_read_hw_time();
4054 _g_bat_sleep_total_time += after_sleep_time - before_sleep_time;
4055
4056 battery_xlog_printk(BAT_LOG_CRTI, "g_spm_timer = %d, sleep_total_time = %d, after_sleep_time = %d, before_sleep_time = %d\n",
4057 g_spm_timer, _g_bat_sleep_total_time, after_sleep_time, before_sleep_time);
4058
4059 if (_g_bat_sleep_total_time >= g_spm_timer) {
4060 bat_spm_timeout = true;
4061 }
4062
4063 battery_meter_ctrl(BATTERY_METER_CMD_GET_HW_OCV, &hw_ocv_after_sleep);
4064 g_sleep_fg_soc = fgauge_read_capacity_by_v(hw_ocv_after_sleep);
4065 g_sleep_fg_ui_soc = BMT_status.SOC;
4066 resume_count++;
4067
4068 sw_vbat = battery_meter_get_battery_voltage(KAL_TRUE);
4069 battery_xlog_printk(BAT_LOG_CRTI, "HW_OCV = %d, SW_VBAT = %d\n", hw_ocv_after_sleep, sw_vbat);
4070
4071 if(hw_ocv_after_sleep < sw_vbat)
4072 {
4073 bm_print(BM_LOG_CRTI, "Ignore HW_OCV : small than SW_VBAT\n");
4074 }
4075 else if( (hw_ocv_after_sleep - sw_vbat) > vbat_diff )
4076 {
4077 bm_print(BM_LOG_CRTI, "Ignore HW_OCV : diff > %d\n", vbat_diff);
4078 }
4079 else
4080 {
4081 if (g_sleep_fg_ui_soc >= g_sleep_fg_soc){
4082 if ((g_sleep_fg_ui_soc - g_sleep_fg_soc) > SLEEP_AFTER_FG_DIFF){
4083 if (( MIN_SUSPEND_CURRENT <= suspend_current)
4084 && (suspend_current < MAX_SUSPEND_CURRENT))
4085 suspend_current = suspend_current + SUSPEND_CURRENT_SETP;
4086 }
4087 else {
4088 suspend_current = UI_REDUCE_CURRENT;
4089 }
4090 }
4091 else {
4092 if ((g_sleep_fg_soc - g_sleep_fg_ui_soc) > SLEEP_AFTER_FG_DIFF){
4093 if (( MIN_SUSPEND_CURRENT < suspend_current)
4094 && (suspend_current <= MAX_SUSPEND_CURRENT))
4095 suspend_current = suspend_current - SUSPEND_CURRENT_SETP;
4096 }
4097 else {
4098 suspend_current = SLEEP_REDUCE_CURRENT;
4099 }
4100 }
4101
4102 printk("<2>""%s g_sleep_fg_ui_soc = %d, g_sleep_fg_soc = %d, hw_ocv_after_sleep = %d, suspend_current = %d, resure_count = %d\n",
4103 __func__, g_sleep_fg_ui_soc, g_sleep_fg_soc, hw_ocv_after_sleep, suspend_current, resume_count);
4104
4105 if((after_sleep_time - before_sleep_time) > 3600)
4106 {
4107 if(hw_ocv_after_sleep != g_hw_ocv_before_sleep)
4108 {
4109 gFG_DOD0 = fgauge_read_d_by_v(hw_ocv_after_sleep);
4110 oam_v_ocv_2 = oam_v_ocv_1 = hw_ocv_after_sleep;
4111 oam_car_1 = 0;
4112 oam_car_2 = 0;
4113 }
4114 else
4115 {
4116 oam_car_delta = suspend_current * (after_sleep_time - before_sleep_time + suspend_oam_time) / 3600;
4117 suspend_oam_time = suspend_current * (after_sleep_time - before_sleep_time + suspend_oam_time) % 3600;
4118 suspend_oam_time = suspend_oam_time / suspend_current;
4119 oam_car_1 += oam_car_delta;
4120 oam_car_2 += oam_car_delta;
4121 }
4122 }
4123 else
4124 {
4125 oam_car_delta = suspend_current * (after_sleep_time - before_sleep_time + suspend_oam_time) / 3600;
4126 suspend_oam_time = suspend_current * (after_sleep_time - before_sleep_time + suspend_oam_time) % 3600;
4127 suspend_oam_time = suspend_oam_time / suspend_current;
4128 oam_car_1 += oam_car_delta;
4129 oam_car_2 += oam_car_delta;
4130 }
4131
4132 bm_print(BM_LOG_CRTI, "sleeptime=(%d)s, be_ocv=(%d), af_ocv=(%d), D0=(%d), car1=(%d), car2=(%d) \n",
4133 (after_sleep_time - before_sleep_time),
4134 g_hw_ocv_before_sleep, hw_ocv_after_sleep, gFG_DOD0, oam_car_1, oam_car_2);
4135 }
4136#endif
4137/*[BUGFIX]-Add-END by TCTSZ.pingao.yang */
4138
4139 //bm_print(BM_LOG_CRTI, "[battery_meter_resume]\n");
4140 return 0;
4141}
4142
4143//-----------------------------------------------------
4144
4145#ifdef CONFIG_OF
4146static const struct of_device_id mt_bat_meter_of_match[] = {
4147 { .compatible = "mediatek,bat_meter", },
4148 {},
4149};
4150
4151MODULE_DEVICE_TABLE(of, mt_bat_meter_of_match);
4152#endif
4153struct platform_device battery_meter_device = {
4154 .name = "battery_meter",
4155 .id = -1,
4156};
4157
4158
4159static struct platform_driver battery_meter_driver = {
4160 .probe = battery_meter_probe,
4161 .remove = battery_meter_remove,
4162 .shutdown = battery_meter_shutdown,
4163 .suspend = battery_meter_suspend,
4164 .resume = battery_meter_resume,
4165 .driver = {
4166 .name = "battery_meter",
4167 },
4168};
4169
4170static int battery_meter_dts_probe(struct platform_device *dev)
4171{
4172 int ret = 0;
4173 /* struct proc_dir_entry *entry = NULL; */
4174 struct proc_dir_entry *battery_dir = NULL;
4175
4176 battery_xlog_printk(BAT_LOG_CRTI, "******** battery_meter_dts_probe!! ********\n");
4177
4178 battery_meter_device.dev.of_node = dev->dev.of_node;
4179 ret = platform_device_register(&battery_meter_device);
4180 if (ret) {
4181 battery_xlog_printk(BAT_LOG_CRTI,
4182 "****[battery_meter_dts_probe] Unable to register device (%d)\n", ret);
4183 return ret;
4184 }
4185 return 0;
4186
4187}
4188
4189static struct platform_driver battery_meter_dts_driver = {
4190 .probe = battery_meter_dts_probe,
4191 .remove = NULL,
4192 .shutdown = NULL,
4193 .suspend = NULL,
4194 .resume = NULL,
4195 .driver = {
4196 .name = "battery_meter_dts",
4197 #ifdef CONFIG_OF
4198 .of_match_table = mt_bat_meter_of_match,
4199 #endif
4200 },
4201};
4202
4203static int __init battery_meter_init(void)
4204{
4205 int ret;
4206
4207#ifdef CONFIG_OF
4208 //
4209#else
4210 ret = platform_device_register(&battery_meter_device);
4211 if (ret) {
4212 bm_print(BM_LOG_CRTI, "[battery_meter_driver] Unable to device register(%d)\n",
4213 ret);
4214 return ret;
4215 }
4216#endif
4217
4218 ret = platform_driver_register(&battery_meter_driver);
4219 if (ret) {
4220 bm_print(BM_LOG_CRTI, "[battery_meter_driver] Unable to register driver (%d)\n",
4221 ret);
4222 return ret;
4223 }
4224#ifdef CONFIG_OF
4225 ret = platform_driver_register(&battery_meter_dts_driver);
4226#endif
4227 bm_print(BM_LOG_CRTI, "[battery_meter_driver] Initialization : DONE\n");
4228
4229 return 0;
4230
4231}
4232#ifdef BATTERY_MODULE_INIT
4233//#if 0
4234late_initcall(battery_meter_init);
4235#else
4236static void __exit battery_meter_exit(void)
4237{
4238}
4239module_init(battery_meter_init);
4240module_exit(battery_meter_exit);
4241#endif
4242
4243MODULE_AUTHOR("James Lo");
4244MODULE_DESCRIPTION("Battery Meter Device Driver");
4245MODULE_LICENSE("GPL");