static int check_battery_changed(struct twl4030_bci_device_info *di) { static int battery_calibration_enabled = 0; int need_recalibration = 0; int upper_limit, lower_limit; if(battery_calibration_enabled) { // Voltage Calibration Complete start_monitor = 0; set_end_of_charge(0); set_charging_timer(0); di->charge_status = POWER_SUPPLY_STATUS_CHARGING; battery_calibration_enabled = 0; printk(KERN_INFO "[BATTERY] ReCalibration Done!\n"); return 2; } if(di->charge_rsoc == POWER_SUPPLY_TYPE_BATTERY) return 0; if(di->battery_present == 0) // Cannot do anything without battery return 0; if((di->temp_C < 0 || di->temp_C > 60) && di->temp_control != UNLIMITED_TEMP_VAL){ // 20120725, [email protected], Enable charging by fake mode. // Ignore when low or high temperature return 0; } // Set Voltage Limit // TODO : 300 and -250 is tuning value. must be verified. upper_limit = 300; lower_limit = -250; // Check battery changed while phone turned on if(di->battery_present == 1 && di->previous_battery_present == 0) { // Battery Inserted need_recalibration = 1; } else { int voltage_diff; voltage_diff = di->voltage_uV - di->previous_voltage_uV; if(voltage_diff > upper_limit) { // too much voltage increase if(di->previous_charge_rsoc != POWER_SUPPLY_TYPE_BATTERY) { need_recalibration = 1; } } else if(voltage_diff < lower_limit) { // too much voltage drop need_recalibration = 1; } } if(need_recalibration) { charging_ic_deactive(); battery_calibration_enabled = 1; di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN; printk(KERN_INFO "[BATTERY] Need To Calibration!\n"); printk(KERN_INFO "[BATTERY] %dmV -> %dmV\n", di->previous_voltage_uV, di->voltage_uV); mdelay(50); // wait for voltage drop - charging ic deactived. max17043_do_calibrate(); // Fuel Gauge Recalibration takes 1~3 sec. } return need_recalibration; }
static void charging_ic_work_func(struct work_struct *work) { printk(KERN_INFO "[charging_msg] %s\n", __FUNCTION__); if(charging_ic_status != CHARGING_IC_DEACTIVE) { printk(KERN_INFO "[Battery] Charging IC - EOC\n"); set_end_of_charge(1); charger_state_update_by_other(); } if(wake_lock_active(&eoc_handle_lock)) wake_unlock(&eoc_handle_lock); }
static void charging_ic_work_func(struct work_struct *work) { printk(KERN_INFO "[charging_msg] %s\n", __FUNCTION__); #if defined(CONFIG_PRODUCT_LGE_LU6800) //20101102 [email protected] To support factory cal to prevent to deactive[START_LGE] charger_state_update_by_other(); //20101102 [email protected] To support factory cal to prevent to deactive[END_LGE] #else if(charging_ic_status != CHARGING_IC_DEACTIVE) { set_end_of_charge(1); //charging_ic_deactive(); charger_state_update_by_other(); printk(KERN_INFO "[Battery] Charging IC - EOC\n"); } #endif }
static int set_battery_charging(struct twl4030_bci_device_info *di) { int trickle_chg_max, trickle_chg_min, trickle_chg_timer_start; max8922_status chr_ic_status = get_charging_ic_status(); if(di->battery_present == 0 || // No Battery State di->charge_rsoc == POWER_SUPPLY_TYPE_BATTERY) { // No Charging Source start_monitor = 0; set_end_of_charge(0); set_charging_timer(0); return 0; } /* * Recharging algorithm * - High Temperature : up to 4.0V * - Normal : up to 4.2V */ // Set maximum charging voltage if((di->temp_C < TEMP_CRITICAL_LOWER || di->temp_C > TEMP_CRITICAL_UPPER) && // Critical Temperature! Must stop charging di->temp_control != UNLIMITED_TEMP_VAL){ // 20120725, [email protected], Enable charging by fake mode. start_monitor = 0; set_end_of_charge(0); set_charging_timer(0); if (di->battery_present == 1) charging_ic_deactive(); return 0; } else if(di->temp_C < TEMP_LIMIT_LOWER || di->temp_C > TEMP_LIMIT_UPPER) { // Charging Limit trickle_chg_max = 4000; trickle_chg_timer_start = 3950; trickle_chg_min = 3900; } else { // Normal Charging trickle_chg_max = 4220; // to unintentional charging stop trickle_chg_timer_start = 4197; trickle_chg_min = 4140; if((di->previous_temp_C < TEMP_LIMIT_LOWER || di->previous_temp_C > TEMP_LIMIT_UPPER) && di->temp_control != UNLIMITED_TEMP_VAL) { // 20120725, [email protected], Enable charging by fake mode. start_monitor = 0; set_end_of_charge(0); set_charging_timer(0); } } // Deactive charger for protect overcharge & monitoring if(chr_ic_status != CHARGING_IC_DEACTIVE) { if(/*di->voltage_uV >= trickle_chg_max ||*/ charging_timeout() || end_of_charge) { // Battery Full Charged Once. Entering Trickle Charging Mode if(!charging_timeout()) // Do not stop charging when timeout occured charging_ic_deactive(); // It's not actually charged full. set_charging_timer(0); set_end_of_charge(0); if(start_monitor == 0) { printk(KERN_DEBUG "[Battery] Trickle Charging Start!\n"); start_monitor = 1; } } else if(di->voltage_uV >= trickle_chg_timer_start) { set_charging_timer(1); } } else if(di->voltage_uV < trickle_chg_min) { // active charger for recharging switch(di->charge_rsoc) { case POWER_SUPPLY_TYPE_MAINS: charging_ic_set_ta_mode(); break; case POWER_SUPPLY_TYPE_USB: charging_ic_set_usb_mode(); break; case POWER_SUPPLY_TYPE_UPS: charging_ic_set_factory_mode(); break; default: break; } } return 0; }