static void chg_thread(struct work_struct *work) { int ret; unsigned int value = 0; int dets; if (disable_chg_timer) { disable_chg_timer = 0; pmic_set_chg_current(0x8); queue_delayed_work(chg_wq, &chg_work, 100); chg_wa_timer = 1; return; } ret = pmic_read_reg(REG_INT_SENSE0, &value, BITFMASK(BIT_CHG_DETS)); if (ret == 0) { dets = BITFEXT(value, BIT_CHG_DETS); pr_debug("dets=%d\n", dets); if (dets == 1) { pmic_get_chg_value(&value); pr_debug("average value=%d\n", value); if ((value <= 3) | ((value & 0x200) != 0)) { pr_debug("%s: Disable the charger\n", __func__); pmic_set_chg_current(0); disable_chg_timer = 1; } queue_delayed_work(chg_wq, &chg_work, 100); chg_wa_timer = 1; } } }
static int pmic_set_charger_current_value(void) { //printk("%s %s %d bChargerIsDCDC=%d\n",__FILE__,__func__,__LINE__,bChargerIsDCDC); if(bChargerIsDCDC){ pmic_set_chg_current(PMIC_SET_DCDC_REG_CHARGE); }else{ pmic_set_chg_current(PMIC_SET_REG_CHARGE); } return 0; }
static int pmic_restart_charging(void) { pmic_set_chg_misc(BAT_TH_CHECK_DIS, 1); pmic_set_chg_misc(AUTO_CHG_DIS, 0); pmic_set_chg_misc(VI_PROGRAM_EN, 1); pmic_set_chg_current(0x8); pmic_set_chg_misc(RESTART_CHG_STAT, 1); return 0; }
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 pmic_battery_probe(struct platform_device *pdev) { int retval = 0; struct mc13892_dev_info *di; pmic_event_callback_t bat_event_callback; pmic_version_t pmic_version; //printk("%s %s %d \n",__FILE__,__func__,__LINE__); /* Only apply battery driver for MC13892 V2.0 due to ENGR108085 */ pmic_version = pmic_get_version(); if (pmic_version.revision < 20) { pr_debug("Battery driver is only applied for MC13892 V2.0\n"); return -1; } if (machine_is_mx50_arm2()) { pr_debug("mc13892 charger is not used for this platform\n"); return -1; } di = kzalloc(sizeof(*di), GFP_KERNEL); if (!di) { retval = -ENOMEM; goto di_alloc_failed; } di->init_charge = -1; platform_set_drvdata(pdev, di); di->charger.name = "mc13892_charger"; di->charger.type = POWER_SUPPLY_TYPE_MAINS; di->charger.properties = mc13892_charger_props; di->charger.num_properties = ARRAY_SIZE(mc13892_charger_props); di->charger.get_property = mc13892_charger_get_property; retval = power_supply_register(&pdev->dev, &di->charger); if (retval) { dev_err(di->dev, "failed to register charger\n"); goto charger_failed; } INIT_DELAYED_WORK(&di->monitor_work, mc13892_battery_work); di->monitor_wqueue = create_singlethread_workqueue(dev_name(&pdev->dev)); if (!di->monitor_wqueue) { retval = -ESRCH; goto workqueue_failed; } queue_delayed_work(di->monitor_wqueue, &di->monitor_work, HZ * 10); //queue_delayed_work(di->monitor_wqueue, &di->monitor_work, msecs_to_jiffies(10000)); pmic_stop_coulomb_counter(); pmic_calibrate_coulomb_counter(); //for get correct voltage on the battery when booting with external power. //chg_thread will change it, when next work (chg_work) is start. pmic_set_chg_current(0); INIT_DELAYED_WORK(&di->calc_capacity,mc13892_compute_battery_capacity_from_CC); queue_delayed_work(di->monitor_wqueue, &di->calc_capacity, 0); INIT_DELAYED_WORK(&chg_work, chg_thread); chg_wq = create_singlethread_workqueue("mxc_chg"); if (!chg_wq) { retval = -ESRCH; goto workqueue_failed; } queue_delayed_work(chg_wq, &chg_work, HZ); di->dev = &pdev->dev; di->bat.name = "mc13892_bat"; di->bat.type = POWER_SUPPLY_TYPE_BATTERY; di->bat.properties = mc13892_battery_props; di->bat.num_properties = ARRAY_SIZE(mc13892_battery_props); di->bat.get_property = mc13892_battery_get_property; di->bat.use_for_apm = 1; di->battery_status = POWER_SUPPLY_STATUS_UNKNOWN; //di->battery_status = POWER_SUPPLY_STATUS_DISCHARGING; retval = power_supply_register(&pdev->dev, &di->bat); if (retval) { dev_err(di->dev, "failed to register battery\n"); goto batt_failed; } bat_event_callback.func = charger_online_event_callback; bat_event_callback.param = (void *) di; pmic_event_subscribe(EVENT_CHGDETI, bat_event_callback); retval = sysfs_create_file(&pdev->dev.kobj, &dev_attr_enable.attr); if (retval) { printk(KERN_ERR "Battery: Unable to register sysdev entry for Battery"); goto workqueue_failed; } chg_wa_is_active = 1; chg_wa_timer = 0; disable_chg_timer = 0; #if defined(PMIC_MC13892_BATTERY_WORK) work_init(); #endif goto success; workqueue_failed: power_supply_unregister(&di->charger); charger_failed: power_supply_unregister(&di->bat); batt_failed: kfree(di); di_alloc_failed: success: dev_dbg(di->dev, "%s battery probed!\n", __func__); return retval; return 0; }