Exemple #1
0
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;
		}
	}
}
Exemple #2
0
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;		
}
Exemple #3
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;
}
Exemple #4
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;
	}
 }
Exemple #5
0
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;
}