static void pmic_chgautovib_funtion(struct work_struct *work) { /* * indicator the device whether connect to charger or USB * 0: disconnect * 1: connect */ int CheckChargerState =0; /* * read the charger current,if the charger current > 240, set the bNeedReset as true; */ int ChargerMA=0; /////////////////////////////////////////////// ////check the device whether connect to charger or USB //// if the device had been connected,we need reset the ////charger current. so we need changes the state, CheckChargerState= get_charger_state(); ChargerMA = get_battery_mA(); //printk("%s %s %d CheckChargerState=%d, state=%d ,ChargerMA=%d\n", // __FILE__,__func__,__LINE__,CheckChargerState,state,ChargerMA); if((CheckChargerState == 1) && (state != CHG_RESTART) && (ChargerMA > 240)){ bNeedReset =true; bProcessSign = false; state = CHG_RESTART; } ///check the result : if the bNeedReset still false;we need mod the timer, //printk("%s %s %d bNeedReset=%d\n",__FILE__,__func__,__LINE__,bNeedReset); if(bNeedReset){ work_destroy(); }else{ queue_delayed_work(chgautovib_wq, &chgautovib_work, 10*HZ); } }
static void mc13892_battery_update_status(struct mc13892_dev_info *di) { unsigned int value; int retval; int old_battery_status = di->battery_status; if (di->battery_status == POWER_SUPPLY_STATUS_UNKNOWN) di->full_counter = 0; if (di->charger_online) { value = get_charger_state(); if (value){ di->battery_status = POWER_SUPPLY_STATUS_CHARGING; }else{ di->battery_status = POWER_SUPPLY_STATUS_NOT_CHARGING; } if (di->battery_status == POWER_SUPPLY_STATUS_NOT_CHARGING) di->full_counter++; else di->full_counter = 0; } else { di->battery_status = POWER_SUPPLY_STATUS_DISCHARGING; di->full_counter = 0; } dev_dbg(di->bat.dev, "bat status: %d\n",di->battery_status); if (old_battery_status != POWER_SUPPLY_STATUS_UNKNOWN /*&& di->battery_status != old_battery_status */){ //if(di->battery_status !=POWER_SUPPLY_STATUS_UNKNOWN){ power_supply_changed(&di->bat); } }
//return a charge of battery in mAh. It get mV. static int mc13892_compute_battery_charge_from_V(int volts) { long c; int chargerState =0; int i = 0; int top_range_v = 0; int top_range_c = 0; chargerState = get_charger_state(); if(chargerState ==1){ if (volts > MAX_Charger_V_LiPo) return BAT_CAP_MAH; if (volts <= MIN_Charger_V_LiPo) return 0; top_range_v=MAX_Charger_V_LiPo; while (volts < charge[i].v) { top_range_v = charge[i].v; top_range_c = charge[i].c; i++; } c = ((volts - charge[i].v) * 100 / (top_range_v - charge[i].v) * (top_range_c - charge[i].c) / 100 + charge[i].c) * BAT_CAP_MAH / 100; }else if(chargerState ==0){ if (volts > MAX_V_LiPo) return BAT_CAP_MAH; if (volts <= MIN_V_LiPo) return 0; top_range_v=MAX_V_LiPo; while (volts < discharge[i].v) { top_range_v = discharge[i].v; top_range_c = discharge[i].c; i++; } c = ((volts - discharge[i].v) * 100 / (top_range_v - discharge[i].v) * (top_range_c - discharge[i].c) / 100 + discharge[i].c) * BAT_CAP_MAH / 100; } return (int)c; }
int get_battery_mA(void) /* get charging current float into battery */ { unsigned short value=0; int bat_curr=0; int bat_cur=0; int chargerState=0; bool bPoweroffProcessSign = false; pmic_get_batt_current(&value); bat_curr = ((value&0x200) ? (value|0xfffffc00) : value); bat_curr = (bat_curr*3000)/512; ////wen add ,only for test, if((-bat_curr) >= 0){ bat_cur = (-bat_curr); }else{ chargerState =get_charger_state(); if(chargerState == 1){ bat_cur = 0; }else{ ///power off,only executed once ////whether check the battaty voltage ? if((!bPoweroffProcessSign) && (get_battery_mV()< 3400)){ pr_notice("Charger current < 0 and Battery voltage < 3.4v, Power off \n"); // orderly_poweroff(1); kernel_power_off(); bPoweroffProcessSign = true; } } } return bat_cur; }
static void chg_thread(struct work_struct *work) { //unsigned int value = 0; int charger=0; int ChargerMA=0; charger = get_charger_state(); switch(state) { case CHG_RESTART: pmic_restart_charging(); pmic_set_chg_current(0); if(charger){ if(get_battery_mV()>BATTARY_VOLTAGE_POWEROFF){ init_charger_timer(); pmic_set_charger_current_value(); state = CHG_CHARGING; }else{ pmic_set_charger_current_value(); msleep(50); if(get_battery_mA()>240){ /* if PMIC can provide 400mA */ init_charger_timer(); state = CHG_CHARGING; }else{ state = CHG_POWER_OFF; } } }else{ state = CHG_DISCHARGING; } queue_delayed_work(chg_wq, &chg_work, HZ*1); break; case CHG_POWER_OFF: pr_notice("Battery level < 3.0V!\n"); pr_notice("After power off, PMIC will charge up battery.\n"); //pmic_set_chg_current(PMIC_SET_REG_CHARGE); /* charge battery during power off */ pmic_set_charger_current_value();/* charge battery during power off */ orderly_poweroff(1); break; case CHG_CHARGING: reset_charger_timer(); ChargerMA = get_battery_mA(); if(charger_timeout() || (ChargerMA<50)){ pmic_set_chg_current(0); state = CHG_DISCHARGING_WITH_CHARGER; } if(!charger){ pmic_set_chg_current(0); state = CHG_DISCHARGING; bProcessSign = false; } if((charger) && (ChargerMA > 0) && (ChargerMA < 60) && (!bProcessSign) && bNeedReset){ pmic_close_charger_led(); bProcessSign = true; } queue_delayed_work(chg_wq, &chg_work, HZ*5); break; case CHG_DISCHARGING: bProcessSign = false; if(charger) state = CHG_RESTART; queue_delayed_work(chg_wq, &chg_work, HZ*10); break; case CHG_DISCHARGING_WITH_CHARGER: if(get_battery_mV() < PMIC_VOLTAGE_MAX_WORK)/*4000*/ state = CHG_RESTART; if(!charger) state = CHG_DISCHARGING; queue_delayed_work(chg_wq, &chg_work, HZ*2); break; } }
static int mc13892_battery_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { struct mc13892_dev_info *di = to_mc13892_dev_info(psy); unsigned int online=0; static int lowBattaryCount =0; //bool bInLowBattaryState = false; online = get_charger_state(); switch (psp) { case POWER_SUPPLY_PROP_STATUS: if (di->battery_status == POWER_SUPPLY_STATUS_UNKNOWN) { mc13892_charger_update_status(di); mc13892_battery_update_status(di); } val->intval = di->battery_status; return 0; default: break; } mc13892_battery_read_status(di); switch (psp) { case POWER_SUPPLY_PROP_VOLTAGE_NOW: val->intval = di->voltage_uV; break; case POWER_SUPPLY_PROP_CURRENT_NOW: val->intval = di->current_uA; break; case POWER_SUPPLY_PROP_CHARGE_NOW: val->intval = di->accum_current_uAh; break; case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: val->intval = PMIC_VOLTAGE_MAX_WORK; break; case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: val->intval = PMIC_VOLTAGE_MIN_WORK; break; case POWER_SUPPLY_PROP_CAPACITY: val->intval = di->capacity; break; case POWER_SUPPLY_PROP_VOLTAGE_MAX: val->intval = PMIC_VOLTAGE_MAX_WORK; break; case POWER_SUPPLY_PROP_VOLTAGE_MIN: val->intval = PMIC_VOLTAGE_MIN_WORK; break; case POWER_SUPPLY_PROP_HEALTH: val->intval = POWER_SUPPLY_HEALTH_GOOD; break; default: return -EINVAL; } return 0; }
static void __ddrrun_func get_initial_ocv(void) { int error = 0; int charger_state, new_battery; unsigned int shutdown_time; pmu_ocv_valid = get_ss_use_pmu_ocv(); shutdown_time = get_shutdown_time(); clear_shutdown_time(); new_battery = is_battery_moved(); charger_state = get_charger_state(); show_cc_reg(); show_coul_time_reg(); SMARTSTAR_COUL_INF("new_battery=%d, charger_state=%d, shutdown_time=%d\n", new_battery, charger_state, shutdown_time); if (!charger_state){ /* power up by press powerkey, ocv be pulled down */ delta_ocv = REG_VAL_5_MV; } else{ /* power up by usb, ocv be pulled up, value tbd */ delta_ocv = 0; //REG_VAL_3_MV; } if (new_battery){ if (charger_state && !pmu_ocv_valid){ error = use_calc_ocv(); } else{ error = use_pmu_ocv(); } } else{ if (shutdown_time > SAVED_OCV_VALID_TIME) { if (charger_state && !pmu_ocv_valid){ error = use_calc_ocv(); } else{ error = use_pmu_ocv(); } } else if (shutdown_time > OCV_VALID_TIME) { if (charger_state && !pmu_ocv_valid){ error = use_saved_ocv(0); } else{ error = use_pmu_ocv(); } } else{ error = use_saved_ocv(1); } } if (error){ #if 0 /* save a flag to notify kernel just use pmu ocv */ save_flag_for_nv_error(); clear_cc_register(); clear_coul_time(); #else use_calc_ocv(); #endif } show_saved_ocv_time_cc(); return; }