import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / power / mediatek / linear_charging.c
diff --git a/drivers/power/mediatek/linear_charging.c b/drivers/power/mediatek/linear_charging.c
new file mode 100644 (file)
index 0000000..8f8551d
--- /dev/null
@@ -0,0 +1,1289 @@
+/*****************************************************************************
+ *
+ * Filename:
+ * ---------
+ *    linear_charging.c
+ *
+ * Project:
+ * --------
+ *   ALPS_Software
+ *
+ * Description:
+ * ------------
+ *   This file implements the interface between BMT and ADC scheduler.
+ *
+ * Author:
+ * -------
+ *  Oscar Liu
+ *
+ *============================================================================
+  * $Revision:   1.0  $
+ * $Modtime:   11 Aug 2005 10:28:16  $
+ * $Log:   //mtkvs01/vmdata/Maui_sw/archives/mcu/hal/peripheral/inc/bmt_chr_setting.h-arc  $
+ *             HISTORY
+ * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *------------------------------------------------------------------------------
+ *------------------------------------------------------------------------------
+ * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
+ *============================================================================
+ ****************************************************************************/
+#include <linux/kernel.h>
+#include <mach/battery_common.h>
+#include <mach/charging.h>
+#include "cust_charging.h"
+#include <mach/mt_boot.h>
+#include <linux/delay.h>
+#include <mach/battery_meter.h>
+#include <linux/mutex.h>
+#include <linux/wakelock.h>
+
+
+ /* ============================================================ // */
+ /* define */
+ /* ============================================================ // */
+ /* cut off to full */
+#define POST_CHARGING_TIME             30 * 60         /* 30mins */
+#define CV_CHECK_DELAT_FOR_BANDGAP     80              /* 80mV */
+#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)
+#define BJT_LIMIT                      1200000         /* 1.2W */
+#ifndef TA_START_VCHR_TUNUNG_VOLTAG
+#define TA_START_VCHR_TUNUNG_VOLTAGE   3700            /* for isink blink issue */
+#define TA_CHARGING_CURRENT            CHARGE_CURRENT_1500_00_MA
+#endif /* TA_START_VCHR_TUNUNG_VOLTAG */
+#endif /* MTK_PUMP_EXPRESS_SUPPORT */
+
+#define FULL_CHECK_TIMES               6
+
+ /* ============================================================ // */
+ /* global variable */
+ /* ============================================================ // */
+kal_uint32             g_bcct_flag = 0;
+CHR_CURRENT_ENUM       g_temp_CC_value = CHARGE_CURRENT_0_00_MA;
+kal_uint32             g_usb_state = USB_UNCONFIGURED;
+kal_uint32             charging_full_current = CHARGING_FULL_CURRENT;  /* mA */
+kal_uint32             v_cc2topoff_threshold = V_CC2TOPOFF_THRES;
+ CHR_CURRENT_ENUM      ulc_cv_charging_current = AC_CHARGER_CURRENT;   
+ kal_bool              ulc_cv_charging_current_flag = KAL_FALSE;
+static bool            usb_unlimited=false;
+
+/* [PLATFORM]-Add-BEGIN by TCTSZ.leo.guo, 04/15/2015,  modify ntc temperature function */
+#ifdef MTK_BATTERY_PROTECT_FEATURE
+kal_bool high_temp_stop_charge = KAL_FALSE;
+#endif
+/* [PLATFORM]-Add-END by TCTSZ.leo.guo */
+
+  /* ///////////////////////////////////////////////////////////////////////////////////////// */
+  /* // JEITA */
+  /* ///////////////////////////////////////////////////////////////////////////////////////// */
+#if defined(CONFIG_MTK_JEITA_STANDARD_SUPPORT)
+int g_jeita_recharging_voltage = JEITA_RECHARGE_VOLTAGE;
+int g_temp_status = TEMP_POS_10_TO_POS_45;
+kal_bool temp_error_recovery_chr_flag = KAL_TRUE;
+#endif
+
+  /* ///////////////////////////////////////////////////////////////////////////////////////// */
+  /* // PUMP EXPRESS */
+  /* ///////////////////////////////////////////////////////////////////////////////////////// */
+#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)
+struct wake_lock TA_charger_suspend_lock;
+CHR_CURRENT_ENUM ta_charging_current = TA_CHARGING_CURRENT;
+int ta_current_level = 5000;
+int ta_pre_vbat = 0;
+kal_bool ta_check_chr_type = KAL_TRUE;
+kal_bool ta_check_ta_control = KAL_FALSE;
+kal_bool ta_vchr_tuning = KAL_FALSE;
+kal_bool first_vchr_det = KAL_TRUE;
+kal_bool ta_cable_out_occur = KAL_FALSE;
+kal_bool is_ta_connect = KAL_FALSE;
+#endif
+
+
+ /* ============================================================ // */
+ /* function prototype */
+ /* ============================================================ // */
+
+
+ /* ============================================================ // */
+ /* extern variable */
+ /* ============================================================ // */
+extern int g_platform_boot_mode;
+
+ /* ============================================================ // */
+ /* extern function */
+ /* ============================================================ // */
+
+
+ /* ============================================================ // */
+void BATTERY_SetUSBState(int usb_state_value)
+{
+#if defined(CONFIG_POWER_EXT)
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY_SetUSBState] in FPGA/EVB, no service\r\n");
+#else
+       if ((usb_state_value < USB_SUSPEND) || ((usb_state_value > USB_CONFIGURED))) {
+               battery_xlog_printk(BAT_LOG_CRTI,
+                                   "[BATTERY] BAT_SetUSBState Fail! Restore to default value\r\n");
+               usb_state_value = USB_UNCONFIGURED;
+       } else {
+               battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] BAT_SetUSBState Success! Set %d\r\n",
+                                   usb_state_value);
+               g_usb_state = usb_state_value;
+       }
+#endif
+}
+
+/* EXPORT_SYMBOL(BATTERY_SetUSBState); */
+
+
+//EXPORT_SYMBOL(BATTERY_SetUSBState);
+
+
+kal_uint32 get_charging_setting_current()
+{
+       return g_temp_CC_value;
+}
+
+
+#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)
+
+static DEFINE_MUTEX(ta_mutex);
+
+static void mtk_ta_decrease(void)
+{
+       kal_bool ta_current_pattern = KAL_FALSE;                // FALSE = decrease
+        
+       //if(BMT_status.charger_exist == KAL_TRUE)      
+       if(ta_cable_out_occur == KAL_FALSE) {
+               battery_charging_control(CHARGING_CMD_SET_TA_CURRENT_PATTERN,&ta_current_pattern);      
+               ta_current_level -= 200;
+       } else {
+               ta_check_chr_type = KAL_TRUE;
+               //is_ta_connect = KAL_FALSE;
+               battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_decrease() Cable out \n");
+       }
+}
+static void mtk_ta_increase(void)
+{
+       kal_bool ta_current_pattern = KAL_TRUE;         // TRUE = increase
+        
+       //if(BMT_status.charger_exist == KAL_TRUE)
+       if(ta_cable_out_occur == KAL_FALSE) {
+               battery_charging_control(CHARGING_CMD_SET_TA_CURRENT_PATTERN,&ta_current_pattern);      
+               ta_current_level += 200;
+        } else {
+               ta_check_chr_type = KAL_TRUE;
+               //is_ta_connect = KAL_FALSE;
+               battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_increase() Cable out \n");
+       }
+}
+
+static void mtk_ta_reset_vchr(void)
+{
+       CHR_CURRENT_ENUM        chr_current = CHARGE_CURRENT_70_00_MA;
+       
+       battery_charging_control(CHARGING_CMD_SET_CURRENT,&chr_current);
+       msleep(250);    // reset Vchr to 5V 
+
+       ta_current_level = 5000;
+
+       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_reset_vchr(): reset Vchr to 5V \n");
+}
+static void mtk_ta_init(void)
+{
+       ta_current_level = 5000;
+       is_ta_connect = KAL_FALSE;
+       ta_pre_vbat = 0;
+       ta_vchr_tuning = KAL_FALSE;
+       ta_check_ta_control = KAL_FALSE;
+       ta_cable_out_occur = KAL_FALSE;
+
+       battery_charging_control(CHARGING_CMD_INIT,NULL);
+}
+static void mtk_ta_detector(void)
+{
+       int real_v_chrA;
+       int real_v_chrB;
+       kal_bool retransmit = KAL_TRUE;
+       kal_uint32 retransmit_count=0;
+       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_detector() start\n");
+       do {
+               real_v_chrA = battery_meter_get_charger_voltage();
+               mtk_ta_decrease();              
+               mtk_ta_decrease();              
+               real_v_chrB = battery_meter_get_charger_voltage();
+
+               if(real_v_chrA - real_v_chrB >= 300) {  /* 0.3V */
+                       retransmit = KAL_FALSE;
+                       is_ta_connect = KAL_TRUE;
+                } else {
+                       retransmit_count++;     
+                       
+                       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_detector(): retransmit_count =%d, chrA=%d, chrB=%d\n", 
+                               retransmit_count, real_v_chrA, real_v_chrB);
+
+                       mtk_ta_reset_vchr();
+               }       
+
+               if((retransmit_count == 3) || (BMT_status.charger_exist == KAL_FALSE)) {
+                       retransmit = KAL_FALSE;
+                       is_ta_connect = KAL_FALSE;
+               }
+                
+       } while((retransmit == KAL_TRUE) && (ta_cable_out_occur == KAL_FALSE));  
+
+       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_detector() ta_current_level=%d, real_v_chrA=%d, real_v_chrB=%d, is_ta_connect=%d\n", 
+               ta_current_level, real_v_chrA, real_v_chrB,is_ta_connect);
+
+       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_detector() end, retry_count=%d, ta_cable_out_occur=%d \n",retransmit_count,ta_cable_out_occur);
+}
+static void mtk_tuning_voltage(int curr_level, int target_level)
+{
+       int is_increase = 0;
+       int exec_level = 0;
+       CHR_CURRENT_ENUM        chr_current = CHARGE_CURRENT_70_00_MA;
+       
+       /* if(BMT_status.charger_exist == KAL_TRUE) */
+       if(ta_cable_out_occur == KAL_FALSE) {
+               battery_xlog_printk(BAT_LOG_CRTI, "mtk_tuning_voltage() start\n");
+        
+               if(curr_level >= target_level) {
+                       exec_level = (curr_level-target_level)/200;
+                       is_increase = 0;                 
+               } else {
+                       exec_level = (target_level-curr_level)/200;
+                       is_increase = 1;
+               }
+
+               if(exec_level == 0) {   /* curr_level == target_level */
+                       battery_charging_control(CHARGING_CMD_SET_CURRENT,&chr_current);
+                       msleep(50);     // for VChr reading to check error occur or not
+               }
+
+                
+               battery_xlog_printk(BAT_LOG_CRTI, "mtk_tuning_voltage() before : ta_current_level=%d, real_v_chr=%d, is_ta_connect=%d, is_increase=%d, exec_level=%d\n", 
+                       ta_current_level, battery_meter_get_charger_voltage(), is_ta_connect, is_increase, exec_level);
+        
+               while((exec_level > 0) && (ta_cable_out_occur == KAL_FALSE)) {
+                       if(is_increase == 1)
+                               mtk_ta_increase();
+                       else
+                               mtk_ta_decrease();
+                       battery_xlog_printk(BAT_LOG_CRTI, "mtk_tuning_voltage() after ta_current_level=%d, real_v_chr=%d, is_ta_connect=%d, is_increase=%d, exec_level=%d\n", 
+                               ta_current_level, battery_meter_get_charger_voltage(), is_ta_connect, is_increase, exec_level);
+        
+                       exec_level--;
+               }
+                
+               battery_xlog_printk(BAT_LOG_CRTI, "mtk_tuning_voltage() end\n");
+       } else {
+               ta_check_chr_type = KAL_TRUE;
+               //is_ta_connect = KAL_FALSE; 
+               battery_xlog_printk(BAT_LOG_CRTI, "mtk_tuning_voltage(), Cable Out\n");
+       }
+}
+static void select_v_chr_candidate(int curr_vbat, int ta_v_chr_candidate[])
+{
+       battery_xlog_printk(BAT_LOG_CRTI, "select_v_chr_candidate() start\n");
+        
+       if(curr_vbat > 4200)             ta_v_chr_candidate[0]=4600;
+       else if(curr_vbat > 4000)  ta_v_chr_candidate[0]=4400;
+       else if(curr_vbat > 3800)  ta_v_chr_candidate[0]=4200;
+       else if(curr_vbat > 3600)  ta_v_chr_candidate[0]=4000;
+       else                                             ta_v_chr_candidate[0]=3800;
+       ta_v_chr_candidate[1]=ta_v_chr_candidate[0]+200;
+       ta_v_chr_candidate[2]=ta_v_chr_candidate[0]+400;
+       ta_v_chr_candidate[3]=ta_v_chr_candidate[0]+600;
+       battery_xlog_printk(BAT_LOG_CRTI, "select_v_chr_candidate() vbat=%d, candidate=%d,%d,%d\n",
+               curr_vbat, ta_v_chr_candidate[1], ta_v_chr_candidate[2], ta_v_chr_candidate[3]);
+        
+       battery_xlog_printk(BAT_LOG_CRTI, "select_v_chr_candidate() end\n");
+}
+
+
+static void mtk_ta_vchr_select(int i,int ta_v_chr_candidate[], int ta_charging_current_candidate[], int *max_charging_current, int *max_charging_current_i)
+{
+       int current_vchr;
+       kal_bool retransmit = KAL_TRUE;
+       kal_uint32 retransmit_count=0;
+
+       current_vchr = battery_meter_get_charger_voltage();
+       if(ta_current_level != 5000 && current_vchr >= 4900) {  /* pattern error before, so reset vchr to 5V */
+               battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_vchr_select() : curr_VChr=%d, ta_current_level=%d\n",current_vchr,ta_current_level);
+
+               mtk_ta_reset_vchr();
+       }
+
+       do {
+               mtk_tuning_voltage(ta_current_level, ta_v_chr_candidate[i]);
+
+               current_vchr = battery_meter_get_charger_voltage();
+               if((abs(current_vchr - ta_current_level) > 300) && (ta_cable_out_occur == KAL_FALSE)) {         /* variation > 0.3V, error occur */
+                       retransmit_count++;
+               
+                       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_vchr_select(): retransmit_count =%d, cur_chr=%d, ta_current_level=%d\n", 
+                               retransmit_count, current_vchr, ta_current_level);
+                       
+                       mtk_ta_reset_vchr(); 
+               } else {
+                       retransmit = KAL_FALSE;
+               }
+
+               if((retransmit_count == 2) || (ta_cable_out_occur == KAL_TRUE)) {
+                       retransmit = KAL_FALSE;
+               }
+
+       } while((retransmit == KAL_TRUE) && (ta_cable_out_occur == KAL_FALSE));         
+
+       battery_charging_control(CHARGING_CMD_SET_CURRENT,&ta_charging_current);        //1.5A
+
+       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_vchr_select() : use 1.5A for select max current\n");
+       msleep(900); // over 800ms to avoid interference pattern
+        
+       ta_charging_current_candidate[i] = battery_meter_get_charging_current_imm();
+
+       /* we hope to choose the less VChr if the current difference between 2 step is not large, so we add weighting for different VChr step */
+       if(i == 1)
+               ta_charging_current_candidate[i] += 100;        // weighting, plus 120mA for Vbat+0.4V
+       else if(i == 2)
+               ta_charging_current_candidate[i] += 50; // weighting, plug 60mA for Vbat+0.6V
+
+       if(ta_charging_current_candidate[i] > *max_charging_current) {
+               *max_charging_current = ta_charging_current_candidate[i];
+               *max_charging_current_i = i;
+       }
+}
+
+  
+static void mtk_ta_BJT_check(void)
+{
+       int curr_vbat = 0;
+       int curr_current = 0;
+       int vchr = 0;
+       int watt = 0;
+
+       vchr = battery_meter_get_charger_voltage();
+       curr_vbat = battery_meter_get_battery_voltage(KAL_TRUE);
+       curr_current = battery_meter_get_charging_current_imm();
+
+       watt = ((vchr - curr_vbat)*curr_current);
+       if(watt > BJT_LIMIT)    //1.2W
+               is_ta_connect = KAL_FALSE;
+
+       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_BJT_check() vchr=%d, vbat=%d, current=%d, Watt=%d, ta_current_level=%d\n",
+               vchr,curr_vbat,curr_current,watt, ta_current_level);
+}                      
+static void battery_pump_express_charger_check(void)
+{
+       if (ta_check_chr_type == KAL_TRUE && BMT_status.charger_type == STANDARD_CHARGER) {
+               mutex_lock(&ta_mutex);
+               wake_lock(&TA_charger_suspend_lock);
+               
+               mtk_ta_reset_vchr();
+               mtk_ta_init();
+               mtk_ta_detector();
+
+               first_vchr_det = KAL_TRUE;
+
+               if(ta_cable_out_occur == KAL_FALSE) {
+                       ta_check_chr_type = KAL_FALSE;
+               } else {
+                       /* need to re-check if the charger plug out during ta detector */
+                       ta_check_chr_type = KAL_TRUE;
+               }
+
+               wake_unlock(&TA_charger_suspend_lock);
+               mutex_unlock(&ta_mutex);
+       }
+
+}
+static void battery_pump_express_algorithm_start(void)
+{
+       int ta_v_chr_candidate[4]={0,0,0,0};
+       int ta_charging_current_candidate[4]={0,0,0,0};
+       int max_charging_current = 0;
+       int max_charging_current_i = 0;
+       int curr_vbat = 0;
+       int i = 0;
+       int ta_cv_vchr;
+#ifdef HIGH_BATTERY_VOLTAGE_SUPPORT
+               kal_uint32 cv_voltage = 4350;
+#else
+               kal_uint32 cv_voltage = 4200;
+#endif
+       
+       mutex_lock(&ta_mutex);
+       wake_lock(&TA_charger_suspend_lock);
+       if(is_ta_connect == KAL_TRUE) {
+               battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_algorithm() start\n");
+                                        
+               curr_vbat = battery_meter_get_battery_voltage(KAL_TRUE);
+               if( ((curr_vbat-ta_pre_vbat)>100) && (curr_vbat < (cv_voltage - (CV_CHECK_DELAT_FOR_BANDGAP+20))) && (curr_vbat > TA_START_VCHR_TUNUNG_VOLTAGE) ) {             /*cv -0.12V && to avoid screen flash( VBAT less than 3.7V) */
+                       ta_pre_vbat = curr_vbat;
+                
+                       select_v_chr_candidate(curr_vbat, ta_v_chr_candidate);
+
+                       if(first_vchr_det == KAL_TRUE) {
+                               for(i=3 ; i>=1 ; i--) {         /* measure  VBAT+0.8V, VBAT+0.6V then VBAT+0.4V */
+                                       if(ta_cable_out_occur == KAL_FALSE)
+                                               mtk_ta_vchr_select(i,ta_v_chr_candidate,ta_charging_current_candidate,&max_charging_current,&max_charging_current_i);
+                               }
+
+                               first_vchr_det = KAL_FALSE;
+                       } else {
+                               for(i=1 ; i<=3 ; i++) {         /* measure VBAT+0.4V,VBAT+0.6V then VBAT+0.8V */
+                                       if(ta_cable_out_occur == KAL_FALSE)
+                                               mtk_ta_vchr_select(i,ta_v_chr_candidate,ta_charging_current_candidate,&max_charging_current,&max_charging_current_i);
+                               }
+                       }
+                       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_algorithm() candidate=%d,%d,%d,%d ; i=%d,%d,%d,%d ; max_charging_current_i=%d\n",
+                               ta_v_chr_candidate[0], ta_v_chr_candidate[1], ta_v_chr_candidate[2], ta_v_chr_candidate[3],
+                               ta_charging_current_candidate[0], ta_charging_current_candidate[1], ta_charging_current_candidate[2],ta_charging_current_candidate[3],
+                               max_charging_current_i
+                               );
+                       mtk_tuning_voltage(ta_current_level, ta_v_chr_candidate[max_charging_current_i]);
+
+                       ta_vchr_tuning = KAL_TRUE;
+                       ta_check_ta_control = KAL_TRUE;
+               } else if(curr_vbat >= (cv_voltage - (CV_CHECK_DELAT_FOR_BANDGAP+20))) {
+                       if(cv_voltage == 4200)
+                               ta_cv_vchr = 4800;
+                       else    // cv 4.35V
+                               ta_cv_vchr = 5000;
+
+                       if(ta_current_level != ta_cv_vchr) {
+                               mtk_tuning_voltage(ta_current_level, ta_cv_vchr);
+                       }       
+
+                       ta_vchr_tuning = KAL_TRUE;
+                       ta_check_ta_control = KAL_FALSE;
+
+                       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_algorithm(),curr_vbat > cv_voltage, ta_current_level=%d, cv_voltage=%d, ta_cv_vchr=%d,",ta_current_level,cv_voltage,ta_cv_vchr);
+               }
+
+               /* --for normal charging */
+               if((is_ta_connect == KAL_TRUE) && (curr_vbat > TA_START_VCHR_TUNUNG_VOLTAGE) &&(ta_check_ta_control == KAL_TRUE)) {     /* to avoid screen flash( VBAT less than 3.7V) */
+                       battery_charging_control(CHARGING_CMD_SET_CURRENT,&ta_charging_current);        /* 1.5A */
+                       battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_algorithm() : detect TA, use 1.5A for normal charging, curr_vbat=%d, ta_pre_vbat=%d, ta_current_level=%d\n",
+                               curr_vbat, ta_pre_vbat, ta_current_level);
+                       //msleep(1500);
+               }
+               //------------------------
+                
+               mtk_ta_BJT_check();
+               battery_xlog_printk(BAT_LOG_CRTI, "mtk_ta_algorithm() end\n");
+       } else {
+               battery_xlog_printk(BAT_LOG_CRTI, "It's not a TA charger, bypass TA algorithm\n");
+       }
+
+       wake_unlock(&TA_charger_suspend_lock);
+       mutex_unlock(&ta_mutex);
+}
+
+#endif
+
+#if defined(CONFIG_MTK_JEITA_STANDARD_SUPPORT)
+
+static BATTERY_VOLTAGE_ENUM select_jeita_cv(void)
+{
+       BATTERY_VOLTAGE_ENUM cv_voltage;
+
+       if (g_temp_status == TEMP_ABOVE_POS_60) {
+               cv_voltage = JEITA_TEMP_ABOVE_POS_60_CV_VOLTAGE;
+       } else if (g_temp_status == TEMP_POS_45_TO_POS_60) {
+               cv_voltage = JEITA_TEMP_POS_45_TO_POS_60_CV_VOLTAGE;
+       } else if (g_temp_status == TEMP_POS_10_TO_POS_45) {
+#ifdef HIGH_BATTERY_VOLTAGE_SUPPORT
+               cv_voltage = BATTERY_VOLT_04_350000_V;
+#else
+               cv_voltage = JEITA_TEMP_POS_10_TO_POS_45_CV_VOLTAGE;
+#endif
+       } else if (g_temp_status == TEMP_POS_0_TO_POS_10) {
+               cv_voltage = JEITA_TEMP_POS_0_TO_POS_10_CV_VOLTAGE;
+       } else if (g_temp_status == TEMP_NEG_10_TO_POS_0) {
+               cv_voltage = JEITA_TEMP_NEG_10_TO_POS_0_CV_VOLTAGE;
+       } else if (g_temp_status == TEMP_BELOW_NEG_10) {
+               cv_voltage = JEITA_TEMP_BELOW_NEG_10_CV_VOLTAGE;
+       } else {
+               cv_voltage = BATTERY_VOLT_04_200000_V;
+       }
+
+       return cv_voltage;
+}
+
+PMU_STATUS do_jeita_state_machine(void)
+{
+       int previous_g_temp_status;
+       BATTERY_VOLTAGE_ENUM cv_voltage;
+
+       previous_g_temp_status = g_temp_status;
+       /* JEITA battery temp Standard */
+       if (BMT_status.temperature >= TEMP_POS_60_THRESHOLD) {
+               battery_xlog_printk(BAT_LOG_CRTI,
+                                   "[BATTERY] Battery Over high Temperature(%d) !!\n\r",
+                                   TEMP_POS_60_THRESHOLD);
+               g_temp_status = TEMP_ABOVE_POS_60;
+               return PMU_STATUS_FAIL;
+       } else if (BMT_status.temperature > TEMP_POS_45_THRESHOLD) {
+               if ((g_temp_status == TEMP_ABOVE_POS_60)
+                   && (BMT_status.temperature >= TEMP_POS_60_THRES_MINUS_X_DEGREE)) {
+                       battery_xlog_printk(BAT_LOG_CRTI,
+                                           "[BATTERY] Battery Temperature between %d and %d,not allow charging yet!!\n\r",
+                                           TEMP_POS_60_THRES_MINUS_X_DEGREE,
+                                           TEMP_POS_60_THRESHOLD);
+                       return PMU_STATUS_FAIL;
+               } else {
+                       battery_xlog_printk(BAT_LOG_CRTI,
+                                           "[BATTERY] Battery Temperature between %d and %d !!\n\r",
+                                           TEMP_POS_45_THRESHOLD, TEMP_POS_60_THRESHOLD);
+                       g_temp_status = TEMP_POS_45_TO_POS_60;
+                       g_jeita_recharging_voltage = JEITA_TEMP_POS_45_TO_POS_60_RECHARGE_VOLTAGE;
+                       v_cc2topoff_threshold = JEITA_TEMP_POS_45_TO_POS_60_CC2TOPOFF_THRESHOLD;
+                       charging_full_current = CHARGING_FULL_CURRENT;
+               }
+       } else if (BMT_status.temperature >= TEMP_POS_10_THRESHOLD) {
+               if (((g_temp_status == TEMP_POS_45_TO_POS_60)
+                    && (BMT_status.temperature >= TEMP_POS_45_THRES_MINUS_X_DEGREE))
+                   || ((g_temp_status == TEMP_POS_0_TO_POS_10)
+                       && (BMT_status.temperature <= TEMP_POS_10_THRES_PLUS_X_DEGREE))) {
+                       battery_xlog_printk(BAT_LOG_CRTI,
+                                           "[BATTERY] Battery Temperature not recovery to normal temperature charging mode yet!!\n\r");
+               } else {
+                       battery_xlog_printk(BAT_LOG_CRTI,
+                                           "[BATTERY] Battery Normal Temperature between %d and %d !!\n\r",
+                                           TEMP_POS_10_THRESHOLD, TEMP_POS_45_THRESHOLD);
+
+                       g_temp_status = TEMP_POS_10_TO_POS_45;
+#ifdef HIGH_BATTERY_VOLTAGE_SUPPORT
+                       g_jeita_recharging_voltage = 4200;
+#else
+                       g_jeita_recharging_voltage = JEITA_TEMP_POS_10_TO_POS_45_RECHARGE_VOLTAGE;
+#endif
+                       v_cc2topoff_threshold = JEITA_TEMP_POS_10_TO_POS_45_CC2TOPOFF_THRESHOLD;
+                       charging_full_current = CHARGING_FULL_CURRENT;
+               }
+       } else if (BMT_status.temperature >= TEMP_POS_0_THRESHOLD) {
+               if ((g_temp_status == TEMP_NEG_10_TO_POS_0 || g_temp_status == TEMP_BELOW_NEG_10)
+                   && (BMT_status.temperature <= TEMP_POS_0_THRES_PLUS_X_DEGREE)) {
+                       if (g_temp_status == TEMP_NEG_10_TO_POS_0) {
+                               battery_xlog_printk(BAT_LOG_CRTI,
+                                                   "[BATTERY] Battery Temperature between %d and %d !!\n\r",
+                                                   TEMP_POS_0_THRES_PLUS_X_DEGREE,
+                                                   TEMP_POS_10_THRESHOLD);
+                       }
+                       if (g_temp_status == TEMP_BELOW_NEG_10) {
+                               battery_xlog_printk(BAT_LOG_CRTI,
+                                                   "[BATTERY] Battery Temperature between %d and %d,not allow charging yet!!\n\r",
+                                                   TEMP_POS_0_THRESHOLD,
+                                                   TEMP_POS_0_THRES_PLUS_X_DEGREE);
+                               return PMU_STATUS_FAIL;
+                       }
+               } else {
+                       battery_xlog_printk(BAT_LOG_CRTI,
+                                           "[BATTERY] Battery Temperature between %d and %d !!\n\r",
+                                           TEMP_POS_0_THRESHOLD, TEMP_POS_10_THRESHOLD);
+                       g_temp_status = TEMP_POS_0_TO_POS_10;
+                       g_jeita_recharging_voltage = JEITA_TEMP_POS_0_TO_POS_10_RECHARGE_VOLTAGE;
+                       v_cc2topoff_threshold = JEITA_TEMP_POS_0_TO_POS_10_CC2TOPOFF_THRESHOLD;
+                       charging_full_current = CHARGING_FULL_CURRENT;
+               }
+       } else if (BMT_status.temperature >= TEMP_NEG_10_THRESHOLD) {
+               if ((g_temp_status == TEMP_BELOW_NEG_10)
+                   && (BMT_status.temperature <= TEMP_NEG_10_THRES_PLUS_X_DEGREE)) {
+                       battery_xlog_printk(BAT_LOG_CRTI,
+                                           "[BATTERY] Battery Temperature between %d and %d,not allow charging yet!!\n\r",
+                                           TEMP_NEG_10_THRESHOLD, TEMP_NEG_10_THRES_PLUS_X_DEGREE);
+                       return PMU_STATUS_FAIL;
+               } else {
+                       battery_xlog_printk(BAT_LOG_CRTI,
+                                           "[BATTERY] Battery Temperature between %d and %d !!\n\r",
+                                           TEMP_NEG_10_THRESHOLD, TEMP_POS_0_THRESHOLD);
+                       g_temp_status = TEMP_NEG_10_TO_POS_0;
+                       g_jeita_recharging_voltage = JEITA_TEMP_NEG_10_TO_POS_0_RECHARGE_VOLTAGE;
+                       v_cc2topoff_threshold = JEITA_TEMP_NEG_10_TO_POS_0_CC2TOPOFF_THRESHOLD;
+                       charging_full_current = JEITA_NEG_10_TO_POS_0_FULL_CURRENT;
+               }
+       } else {
+               battery_xlog_printk(BAT_LOG_CRTI,
+                                   "[BATTERY] Battery below low Temperature(%d) !!\n\r",
+                                   TEMP_NEG_10_THRESHOLD);
+               g_temp_status = TEMP_BELOW_NEG_10;
+               return PMU_STATUS_FAIL;
+       }
+
+       /* set CV after temperature changed */
+       if (g_temp_status != previous_g_temp_status) {
+               cv_voltage = select_jeita_cv();
+               battery_charging_control(CHARGING_CMD_SET_CV_VOLTAGE, &cv_voltage);
+       }
+
+       return PMU_STATUS_OK;
+}
+
+
+static void set_jeita_charging_current(void)
+{
+#ifdef CONFIG_USB_IF
+       if (BMT_status.charger_type == STANDARD_HOST)
+               return;
+#endif
+
+       if (g_temp_status == TEMP_NEG_10_TO_POS_0) {
+               g_temp_CC_value = CHARGE_CURRENT_200_00_MA;     /* for low temp */
+               battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] JEITA set charging current : %d\r\n",
+                                   g_temp_CC_value);
+       }
+}
+
+#endif
+
+bool get_usb_current_unlimited(void)
+{
+       if (BMT_status.charger_type == STANDARD_HOST || BMT_status.charger_type == CHARGING_HOST)
+               return usb_unlimited;
+       else
+               return false;
+}
+
+void set_usb_current_unlimited(bool enable)
+{
+       usb_unlimited = enable;
+}
+
+void select_charging_curret_bcct(void)
+{
+       /* done on set_bat_charging_current_limit */
+}
+
+
+kal_uint32 set_bat_charging_current_limit(int current_limit)
+{
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] set_bat_charging_current_limit (%d)\r\n",
+                           current_limit);
+
+       if (current_limit != -1) {
+               g_bcct_flag = 1;
+
+               if (current_limit < 70)
+                       g_temp_CC_value = CHARGE_CURRENT_0_00_MA;
+               else if (current_limit < 200)
+                       g_temp_CC_value = CHARGE_CURRENT_70_00_MA;
+               else if (current_limit < 300)
+                       g_temp_CC_value = CHARGE_CURRENT_200_00_MA;
+               else if (current_limit < 400)
+                       g_temp_CC_value = CHARGE_CURRENT_300_00_MA;
+               else if (current_limit < 450)
+                       g_temp_CC_value = CHARGE_CURRENT_400_00_MA;
+               else if (current_limit < 550)
+                       g_temp_CC_value = CHARGE_CURRENT_450_00_MA;
+               else if (current_limit < 650)
+                       g_temp_CC_value = CHARGE_CURRENT_550_00_MA;
+               else if (current_limit < 700)
+                       g_temp_CC_value = CHARGE_CURRENT_650_00_MA;
+               else if (current_limit < 800)
+                       g_temp_CC_value = CHARGE_CURRENT_700_00_MA;
+               else if (current_limit < 900)
+                       g_temp_CC_value = CHARGE_CURRENT_800_00_MA;
+               else if (current_limit < 1000)
+                       g_temp_CC_value = CHARGE_CURRENT_900_00_MA;
+               else if (current_limit < 1100)
+                       g_temp_CC_value = CHARGE_CURRENT_1000_00_MA;
+               else if (current_limit < 1200)
+                       g_temp_CC_value = CHARGE_CURRENT_1100_00_MA;
+               else if (current_limit < 1300)
+                       g_temp_CC_value = CHARGE_CURRENT_1200_00_MA;
+               else if (current_limit < 1400)
+                       g_temp_CC_value = CHARGE_CURRENT_1300_00_MA;
+               else if (current_limit < 1500)
+                       g_temp_CC_value = CHARGE_CURRENT_1400_00_MA;
+               else if (current_limit < 1600)
+                       g_temp_CC_value = CHARGE_CURRENT_1500_00_MA;
+               else if (current_limit == 1600)
+                       g_temp_CC_value = CHARGE_CURRENT_1600_00_MA;
+               else
+                       g_temp_CC_value = CHARGE_CURRENT_450_00_MA;
+       } else {
+               /* change to default current setting */
+               g_bcct_flag = 0;
+       }
+
+       wake_up_bat();
+
+       return g_bcct_flag;
+}
+
+void set_bat_sw_cv_charging_current_limit(int current_limit)
+{
+    battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] set_bat_sw_cv_charging_current_limit (%d)\r\n", current_limit);
+
+    if(current_limit <= CHARGE_CURRENT_70_00_MA)         ulc_cv_charging_current=CHARGE_CURRENT_0_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_200_00_MA)   ulc_cv_charging_current=CHARGE_CURRENT_70_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_300_00_MA)   ulc_cv_charging_current=CHARGE_CURRENT_200_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_400_00_MA)   ulc_cv_charging_current=CHARGE_CURRENT_300_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_450_00_MA)   ulc_cv_charging_current=CHARGE_CURRENT_400_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_550_00_MA)   ulc_cv_charging_current=CHARGE_CURRENT_450_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_650_00_MA)   ulc_cv_charging_current=CHARGE_CURRENT_550_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_700_00_MA)   ulc_cv_charging_current=CHARGE_CURRENT_650_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_800_00_MA)   ulc_cv_charging_current=CHARGE_CURRENT_700_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_900_00_MA)   ulc_cv_charging_current=CHARGE_CURRENT_800_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_1000_00_MA)  ulc_cv_charging_current=CHARGE_CURRENT_900_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_1100_00_MA)  ulc_cv_charging_current=CHARGE_CURRENT_1000_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_1200_00_MA)  ulc_cv_charging_current=CHARGE_CURRENT_1100_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_1300_00_MA)  ulc_cv_charging_current=CHARGE_CURRENT_1200_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_1400_00_MA)  ulc_cv_charging_current=CHARGE_CURRENT_1300_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_1500_00_MA)  ulc_cv_charging_current=CHARGE_CURRENT_1400_00_MA;
+    else if(current_limit <= CHARGE_CURRENT_1600_00_MA)  ulc_cv_charging_current=CHARGE_CURRENT_1500_00_MA;
+    else                            ulc_cv_charging_current=CHARGE_CURRENT_450_00_MA;
+}
+
+void select_charging_curret(void)
+{
+       if (g_ftm_battery_flag) {
+               battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] FTM charging : %d\r\n",
+                                   charging_level_data[0]);
+               g_temp_CC_value = charging_level_data[0];
+       } else {
+               if (BMT_status.charger_type == STANDARD_HOST) {
+#ifdef CONFIG_USB_IF
+                       {
+                               if (g_usb_state == USB_SUSPEND) {
+                                       g_temp_CC_value = USB_CHARGER_CURRENT_SUSPEND;
+                               } else if (g_usb_state == USB_UNCONFIGURED) {
+                                       g_temp_CC_value = USB_CHARGER_CURRENT_UNCONFIGURED;
+                               } else if (g_usb_state == USB_CONFIGURED) {
+                                       g_temp_CC_value = USB_CHARGER_CURRENT_CONFIGURED;
+                               } else {
+                                       g_temp_CC_value = USB_CHARGER_CURRENT_UNCONFIGURED;
+                               }
+
+                               battery_xlog_printk(BAT_LOG_CRTI,
+                                                   "[BATTERY] STANDARD_HOST CC mode charging : %d on %d state\r\n",
+                                                   g_temp_CC_value, g_usb_state);
+                       }
+#else
+                       {
+                               g_temp_CC_value = USB_CHARGER_CURRENT;
+                       }
+#endif
+               } else if (BMT_status.charger_type == NONSTANDARD_CHARGER) {
+                       g_temp_CC_value = NON_STD_AC_CHARGER_CURRENT;
+               } else if (BMT_status.charger_type == STANDARD_CHARGER) {
+                       g_temp_CC_value = AC_CHARGER_CURRENT;
+#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)
+                       if(is_ta_connect == KAL_TRUE && ta_vchr_tuning == KAL_TRUE)
+                               g_temp_CC_value = CHARGE_CURRENT_1500_00_MA;
+#endif
+               } else if (BMT_status.charger_type == CHARGING_HOST) {
+                       g_temp_CC_value = CHARGING_HOST_CHARGER_CURRENT;
+               } else if (BMT_status.charger_type == APPLE_2_1A_CHARGER) {
+                       g_temp_CC_value = APPLE_2_1A_CHARGER_CURRENT;
+               } else if (BMT_status.charger_type == APPLE_1_0A_CHARGER) {
+                       g_temp_CC_value = APPLE_1_0A_CHARGER_CURRENT;
+               } else if (BMT_status.charger_type == APPLE_0_5A_CHARGER) {
+                       g_temp_CC_value = APPLE_0_5A_CHARGER_CURRENT;
+               } else {
+                       g_temp_CC_value = CHARGE_CURRENT_70_00_MA;
+               }
+
+               battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] Default CC mode charging : %d\r\n",
+                                   g_temp_CC_value);
+
+#if defined(CONFIG_MTK_JEITA_STANDARD_SUPPORT)
+               set_jeita_charging_current();
+#endif
+       }
+}
+
+
+
+
+static kal_uint32 charging_full_check(void)
+{
+       kal_uint32 status = KAL_FALSE;
+
+#if defined(POST_TIME_ENABLE)
+       static kal_uint32 post_charging_time = 0; 
+
+       if (post_charging_time >= POST_CHARGING_TIME) {
+               status = KAL_TRUE;
+               post_charging_time = 0;
+
+               battery_xlog_printk(BAT_LOG_CRTI,
+                                   "[BATTERY] Battery real full and disable charging on %d mA\n",
+                                   BMT_status.ICharging);
+       } else if (post_charging_time > 0) {
+               post_charging_time += BAT_TASK_PERIOD;
+               battery_xlog_printk(BAT_LOG_CRTI,
+                                   "[BATTERY] post_charging_time=%d,POST_CHARGING_TIME=%d\n",
+                                   post_charging_time, POST_CHARGING_TIME);
+       } else if ((BMT_status.TOPOFF_charging_time > 60)
+                  && (BMT_status.ICharging <= charging_full_current)) {
+               post_charging_time = BAT_TASK_PERIOD;
+               battery_xlog_printk(BAT_LOG_CRTI,
+                                   "[BATTERY] Enter Post charge, post_charging_time=%d,POST_CHARGING_TIME=%d\n",
+                                   post_charging_time, POST_CHARGING_TIME);
+       } else {
+               post_charging_time = 0;
+       }
+#else
+       static kal_uint8 full_check_count = 0;
+
+       if (BMT_status.ICharging <= charging_full_current) {
+               full_check_count++;
+               if (full_check_count >= FULL_CHECK_TIMES) {
+/* [PLATFORM]-Add-BEGIN by TCTSZ.leo.guo, 04/15/2015,  modify ntc temperature function */
+#ifdef MTK_BATTERY_PROTECT_FEATURE
+                       if (BMT_status.temperature < MAX_LIMIT_CHARGE_TEMPERATURE) {
+                               status = KAL_TRUE;
+                       }
+                       else {
+                               high_temp_stop_charge = KAL_TRUE;
+                       }
+#else
+                       status = KAL_TRUE;
+#endif
+/* [PLATFORM]-Add-END by TCTSZ.leo.guo */
+                       full_check_count = 0;
+                       battery_xlog_printk(BAT_LOG_CRTI,
+                                           "[BATTERY] Battery full and disable charging on %d mA\n",
+                                           BMT_status.ICharging);
+               }
+       } else {
+               full_check_count = 0;
+       }
+#endif
+
+       return status;
+}
+
+
+static void charging_current_calibration(void)
+{
+       kal_int32 bat_isense_offset;
+#if 0
+       kal_int32 bat_vol = battery_meter_get_battery_voltage();
+       kal_int32 Vsense = battery_meter_get_VSense();
+
+       bat_isense_offset = bat_vol - Vsense;
+
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] bat_vol=%d, Vsense=%d, offset=%d \r\n",
+                           bat_vol, Vsense, bat_isense_offset);
+#else
+       bat_isense_offset = 0;
+#endif
+
+       battery_meter_sync(bat_isense_offset);
+}
+
+static void pchr_sw_cv_charing_current_check(void)
+{
+       kal_bool charging_enable = KAL_TRUE;
+       kal_uint32 csdac_full_flag = KAL_TRUE;
+
+       battery_charging_control(CHARGING_CMD_SET_CURRENT,&ulc_cv_charging_current);
+       battery_charging_control(CHARGING_CMD_ENABLE,&charging_enable);
+
+       msleep(192); 
+
+       battery_charging_control(CHARGING_CMD_GET_CSDAC_FALL_FLAG,&csdac_full_flag);
+
+       if(csdac_full_flag == KAL_TRUE) {
+               ulc_cv_charging_current = battery_meter_get_charging_current() * 100;   /* get immedeate charging current and align to enum value */
+       }       
+       
+       while(csdac_full_flag == KAL_TRUE &&  ulc_cv_charging_current !=CHARGE_CURRENT_0_00_MA) {
+               set_bat_sw_cv_charging_current_limit(ulc_cv_charging_current);
+               battery_charging_control(CHARGING_CMD_SET_CURRENT,&ulc_cv_charging_current);
+               ulc_cv_charging_current_flag = KAL_TRUE;
+
+               msleep(192);    /* large than 512 code x 0.25ms */
+               
+               battery_charging_control(CHARGING_CMD_GET_CSDAC_FALL_FLAG,&csdac_full_flag);
+
+               battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] Sw CV set charging current, csdac_full_flag=%d, current=%d !\n",csdac_full_flag,ulc_cv_charging_current);
+       }
+
+       if(ulc_cv_charging_current == CHARGE_CURRENT_0_00_MA)
+               battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] Sw CV set charging current Error!\n");
+}
+
+static void pchr_turn_on_charging(void)
+{
+#if !defined(CONFIG_MTK_JEITA_STANDARD_SUPPORT)
+       BATTERY_VOLTAGE_ENUM cv_voltage;
+#endif
+       kal_uint32 charging_enable = KAL_TRUE;
+
+       battery_xlog_printk(BAT_LOG_FULL, "[BATTERY] pchr_turn_on_charging()!\r\n");
+
+       if (BMT_status.bat_charging_state == CHR_ERROR) {
+               battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] Charger Error, turn OFF charging !\n");
+
+               charging_enable = KAL_FALSE;
+       } else if ((g_platform_boot_mode == META_BOOT) || (g_platform_boot_mode == ADVMETA_BOOT)) {
+               battery_xlog_printk(BAT_LOG_CRTI,
+                                   "[BATTERY] In meta or advanced meta mode, disable charging.\n");
+               charging_enable = KAL_FALSE;
+       } else {
+               /*HW initialization */
+               battery_xlog_printk(BAT_LOG_FULL, "charging_hw_init\n");
+               battery_charging_control(CHARGING_CMD_INIT, NULL);
+
+#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)
+               battery_pump_express_algorithm_start();
+#endif
+
+               /* Set Charging Current */
+               if (get_usb_current_unlimited()) {
+                       g_temp_CC_value = AC_CHARGER_CURRENT;
+                       battery_xlog_printk(BAT_LOG_FULL, "USB_CURRENT_UNLIMITED, use AC_CHARGER_CURRENT\n" );
+               } else {
+                       if (g_bcct_flag == 1) {
+                               battery_xlog_printk(BAT_LOG_FULL,
+                                           "[BATTERY] select_charging_curret_bcct !\n");
+                               select_charging_curret_bcct();
+                       } else {
+                               battery_xlog_printk(BAT_LOG_FULL, "[BATTERY] select_charging_current !\n");
+                               select_charging_curret();
+                       }
+               }
+
+               if (g_temp_CC_value == CHARGE_CURRENT_0_00_MA) {
+                       charging_enable = KAL_FALSE;
+                       battery_xlog_printk(BAT_LOG_CRTI,
+                                       "[BATTERY] charging current is set 0mA, turn off charging !\r\n");
+               } else {
+#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)
+                       if(ta_check_ta_control == KAL_FALSE)
+#endif 
+                       {
+                               if(ulc_cv_charging_current_flag == KAL_TRUE)
+                                       battery_charging_control(CHARGING_CMD_SET_CURRENT,&ulc_cv_charging_current);
+                               else
+                                       battery_charging_control(CHARGING_CMD_SET_CURRENT,&g_temp_CC_value);
+                       }
+
+                       /* Set CV */
+#if !defined(CONFIG_MTK_JEITA_STANDARD_SUPPORT)
+#ifdef HIGH_BATTERY_VOLTAGE_SUPPORT
+                       cv_voltage = BATTERY_VOLT_04_350000_V;
+#else
+                       cv_voltage = BATTERY_VOLT_04_200000_V;
+#endif
+/* [PLATFORM]-Add-BEGIN by TCTSZ.leo.guo, 04/15/2015,  modify ntc temperature function */
+#ifdef MTK_BATTERY_PROTECT_FEATURE
+/*Battery temperature more than 45 degree or less than 55 degree, try to limit max voltage*/
+                       if((BMT_status.temperature >= MAX_LIMIT_CHARGE_TEMPERATURE) && (BMT_status.temperature <= MAX_CHARGE_TEMPERATURE) )
+                       {
+                               cv_voltage = BATTERY_VOLT_04_100000_V;
+                               battery_xlog_printk(BAT_LOG_CRTI,
+                                       "[BATTERY] temperature more than 45 degree or less than 55 degree, try to limit max voltage !\r\n");
+                       }
+#endif
+/* [PLATFORM]-Add-END by TCTSZ.leo.guo */
+                       battery_charging_control(CHARGING_CMD_SET_CV_VOLTAGE, &cv_voltage);
+#endif
+               }
+       }
+
+       /* enable/disable charging */
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] pchr_turn_on_charging(), enable =%d \r\n",
+                           charging_enable);
+       battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);
+
+
+}
+
+
+PMU_STATUS BAT_PreChargeModeAction(void)
+{
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] Pre-CC mode charge, timer=%d on %d !!\n\r",
+                           BMT_status.PRE_charging_time, BMT_status.total_charging_time);
+
+       BMT_status.PRE_charging_time += BAT_TASK_PERIOD;
+       BMT_status.CC_charging_time = 0;
+       BMT_status.TOPOFF_charging_time = 0;
+       BMT_status.total_charging_time += BAT_TASK_PERIOD;
+
+       select_charging_curret();
+       ulc_cv_charging_current = g_temp_CC_value;
+       ulc_cv_charging_current_flag = KAL_FALSE;
+
+       if (BMT_status.UI_SOC == 100) {
+               BMT_status.bat_charging_state = CHR_BATFULL;
+               BMT_status.bat_full = KAL_TRUE;
+               g_charging_full_reset_bat_meter = KAL_TRUE;
+       } else if (BMT_status.bat_vol > V_PRE2CC_THRES) {
+               BMT_status.bat_charging_state = CHR_CC;
+       }
+
+#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)//defined(MTK_LINEAR_CHARGER_NO_DISCHARGE)    
+       // no disable charging
+#else
+       {
+               kal_bool charging_enable = KAL_FALSE;
+/* [PLATFORM]-MOD-BEGIN by TCTSZ huichen@tcl.com, 06/18/2015,  disable PWM charge mode FR-1027565*/
+#if 0
+
+               {
+               int int_CHR_CON1;
+               int ret;
+               ret=pmic_config_interface(CHR_CON0,0x0,0x1,0x0);
+               ret=pmic_read_interface(CHR_CON0,(&int_CHR_CON1),0x1,0x0);
+               printk("BAT_PreChargeModeAction OVP  Reg[0x%x]=0x%x\n", CHR_CON0, int_CHR_CON1);
+
+
+               /*Charging 9s and discharging 1s : start */
+               battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);
+               msleep(1000);
+               ret=pmic_read_interface(CHR_CON0,(&int_CHR_CON1),0x1,0x0);
+               printk("BAT_PreChargeModeAction OVP  Reg[0x%x]=0x%x\n", CHR_CON0, int_CHR_CON1);
+       }
+#endif
+/* [PLATFORM]-MOD-END by TCTSZ huichen@tcl.com, 06/18/2015*/
+       }
+#endif
+
+       charging_current_calibration();
+       pchr_turn_on_charging();
+/* [PLATFORM]-MOD-BEGIN by TCTSZ huichen@tcl.com, 05/18/2015,  modify OVP function FR-1005346*/
+#if 0
+       msleep(50);//need sleep
+       pmic_config_interface(CHR_CON0,0x1,0x1,0x0);
+#endif
+/* [PLATFORM]-MOD-END by TCTSZ huichen@tcl.com, 05/18/2015*/
+       return PMU_STATUS_OK;
+}
+
+
+PMU_STATUS BAT_ConstantCurrentModeAction(void)
+{
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] CC mode charge, timer=%d on %d !!\n\r",
+                           BMT_status.CC_charging_time, BMT_status.total_charging_time);
+
+       BMT_status.PRE_charging_time = 0;
+       BMT_status.CC_charging_time += BAT_TASK_PERIOD;
+       BMT_status.TOPOFF_charging_time = 0;
+       BMT_status.total_charging_time += BAT_TASK_PERIOD;
+
+       ulc_cv_charging_current_flag = KAL_FALSE;
+       ulc_cv_charging_current = g_temp_CC_value;
+
+       if (BMT_status.bat_vol > v_cc2topoff_threshold) {
+               BMT_status.bat_charging_state = CHR_TOP_OFF;
+       }
+
+#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)//defined(MTK_LINEAR_CHARGER_NO_DISCHARGE)
+       // no disable charging#else
+#else
+       {
+
+
+               kal_bool charging_enable = KAL_FALSE;
+/* [PLATFORM]-MOD-BEGIN by TCTSZ huichen@tcl.com, 06/18/2015,  disable PWM charge mode FR-1027565*/
+#if 0
+               {
+               int int_CHR_CON1;
+               int ret;
+               ret=pmic_config_interface(CHR_CON0,0x0,0x1,0x0);
+               ret=pmic_read_interface(CHR_CON0,(&int_CHR_CON1),0x1,0x0);
+               printk("BAT_PreChargeModeAction OVP  Reg[0x%x]=0x%x\n", CHR_CON0, int_CHR_CON1);
+
+               /* Charging 9s and discharging 1s : start */
+               battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);
+               msleep(1000);
+               ret=pmic_read_interface(CHR_CON0,(&int_CHR_CON1),0x1,0x0);
+               printk("BAT_PreChargeModeAction OVP  Reg[0x%x]=0x%x\n", CHR_CON0, int_CHR_CON1);
+       }
+#endif
+/* [PLATFORM]-MOD-END by TCTSZ huichen@tcl.com, 06/18/2015*/
+
+
+       }       
+#endif
+
+       charging_current_calibration();
+
+       pchr_turn_on_charging();
+/* [PLATFORM]-MOD-BEGIN by TCTSZ huichen@tcl.com, 05/18/2015,  modify OVP function FR-1005346*/
+#if 0
+       msleep(50);
+       pmic_config_interface(CHR_CON0,0x1,0x1,0x0);
+#endif
+/* [PLATFORM]-MOD-END by TCTSZ huichen@tcl.com, 05/18/2015*/
+       return PMU_STATUS_OK;
+}
+
+
+PMU_STATUS BAT_TopOffModeAction(void)
+{
+       kal_uint32 charging_enable = KAL_FALSE;
+#ifdef HIGH_BATTERY_VOLTAGE_SUPPORT
+       kal_uint32 cv_voltage = 4350;
+#else
+       kal_uint32 cv_voltage = 4200;
+#endif
+
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] Top Off mode charge, timer=%d on %d !!\n\r",
+                           BMT_status.TOPOFF_charging_time, BMT_status.total_charging_time);
+
+       BMT_status.PRE_charging_time = 0;
+       BMT_status.CC_charging_time = 0;
+       BMT_status.TOPOFF_charging_time += BAT_TASK_PERIOD;
+       BMT_status.total_charging_time += BAT_TASK_PERIOD;
+
+
+       if(BMT_status.bat_vol > (cv_voltage-CV_CHECK_DELAT_FOR_BANDGAP)) {      /* CV - 0.08V */
+               pchr_sw_cv_charing_current_check();
+       }
+       pchr_turn_on_charging();
+
+       if ((BMT_status.TOPOFF_charging_time >= MAX_CV_CHARGING_TIME)
+           || (charging_full_check() == KAL_TRUE)) {
+               BMT_status.bat_charging_state = CHR_BATFULL;
+               BMT_status.bat_full = KAL_TRUE;
+               g_charging_full_reset_bat_meter = KAL_TRUE;
+
+               /*  Disable charging */
+               battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);
+       }
+
+       return PMU_STATUS_OK;
+}
+
+
+PMU_STATUS BAT_BatteryFullAction(void)
+{
+       kal_uint32 charging_enable = KAL_FALSE;
+
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] Battery full !!\n\r");
+
+       BMT_status.bat_full = KAL_TRUE;
+       BMT_status.total_charging_time = 0;
+       BMT_status.PRE_charging_time = 0;
+       BMT_status.CC_charging_time = 0;
+       BMT_status.TOPOFF_charging_time = 0;
+       BMT_status.POSTFULL_charging_time = 0;
+       BMT_status.bat_in_recharging_state = KAL_FALSE;
+
+
+#if defined(CONFIG_MTK_JEITA_STANDARD_SUPPORT)
+       if (BMT_status.bat_vol < g_jeita_recharging_voltage)
+#else
+       if (BMT_status.bat_vol < RECHARGING_VOLTAGE)
+#endif
+       {
+               battery_xlog_printk(BAT_LOG_CRTI,
+                                   "[BATTERY] Battery Enter Re-charging!! , vbat=(%d)\n\r",
+                                   BMT_status.bat_vol);
+
+               BMT_status.bat_in_recharging_state = KAL_TRUE;
+               BMT_status.bat_charging_state = CHR_CC;
+               ulc_cv_charging_current = g_temp_CC_value;
+               ulc_cv_charging_current_flag = KAL_FALSE;
+       }
+
+       /*  Disable charging */
+       battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);
+
+       return PMU_STATUS_OK;
+}
+
+
+PMU_STATUS BAT_BatteryHoldAction(void)
+{
+       kal_uint32 charging_enable;
+
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] Hold mode !!\n\r");
+
+       if (BMT_status.bat_vol < TALKING_RECHARGE_VOLTAGE || g_call_state == CALL_IDLE) {
+               BMT_status.bat_charging_state = CHR_CC;
+               battery_xlog_printk(BAT_LOG_CRTI,
+                                   "[BATTERY] Exit Hold mode and Enter CC mode !!\n\r");
+       }
+
+       /*  Disable charger */
+       charging_enable = KAL_FALSE;
+       battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);
+
+       return PMU_STATUS_OK;
+}
+
+
+PMU_STATUS BAT_BatteryStatusFailAction(void)
+{
+       kal_uint32 charging_enable;
+
+       battery_xlog_printk(BAT_LOG_CRTI, "[BATTERY] BAD Battery status... Charging Stop !!\n\r");
+
+#if defined(CONFIG_MTK_JEITA_STANDARD_SUPPORT)
+       if ((g_temp_status == TEMP_ABOVE_POS_60) || (g_temp_status == TEMP_BELOW_NEG_10)) {
+               temp_error_recovery_chr_flag = KAL_FALSE;
+       }
+       if ((temp_error_recovery_chr_flag == KAL_FALSE) && (g_temp_status != TEMP_ABOVE_POS_60)
+           && (g_temp_status != TEMP_BELOW_NEG_10)) {
+               temp_error_recovery_chr_flag = KAL_TRUE;
+               BMT_status.bat_charging_state = CHR_PRE;
+       }
+#endif
+
+       BMT_status.total_charging_time = 0;
+       BMT_status.PRE_charging_time = 0;
+       BMT_status.CC_charging_time = 0;
+       BMT_status.TOPOFF_charging_time = 0;
+       BMT_status.POSTFULL_charging_time = 0;
+
+       /*  Disable charger */
+       charging_enable = KAL_FALSE;
+       battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);
+
+       return PMU_STATUS_OK;
+}
+
+
+void mt_battery_charging_algorithm(void)
+{
+#if defined(CONFIG_MTK_PUMP_EXPRESS_SUPPORT)
+       battery_pump_express_charger_check();
+#endif
+       switch (BMT_status.bat_charging_state) {
+       case CHR_PRE:
+               BAT_PreChargeModeAction();
+               break;
+
+       case CHR_CC:
+               BAT_ConstantCurrentModeAction();
+               break;
+
+       case CHR_TOP_OFF:
+               BAT_TopOffModeAction();
+               break;
+
+       case CHR_BATFULL:
+               BAT_BatteryFullAction();
+               break;
+
+       case CHR_HOLD:
+               BAT_BatteryHoldAction();
+               break;
+
+       case CHR_ERROR:
+               BAT_BatteryStatusFailAction();
+               break;
+       }
+
+}