static void rk29_adc_battery_lowpower_check(struct rk29_adc_battery_data *bat)
{
	int i;
	int level, oldlevel;
	struct rk29_adc_battery_platform_data *pdata = bat->pdata;

	printk("%s--%d:\n", __FUNCTION__, __LINE__);

	old_charge_level = -1;
	pSamples = bat->adc_samples;

	adc_sync_read(bat->client); //start adc sample
	level = oldlevel = rk29_adc_battery_status_samples(bat); //init charge status

	/* Fill sample buffer with values */
	bat->full_times = 0;
	for (i = 0; i < NUM_VOLTAGE_SAMPLE; i++) //0.3 s
	{
		mdelay(1);
		rk29_adc_battery_voltage_samples(bat); //get voltage
		//level = rk29_adc_battery_status_samples(bat);       //check charge status
		level = rk29_adc_battery_get_charge_level(bat);
		if (oldlevel != level)
		{
			oldlevel = level; //if charge status changed, reset sample
			i = 0;
		}
	}

	bat->bat_capacity = rk29_adc_battery_voltage_to_capacity(bat, bat->bat_voltageAvg);

	bat->bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
	if (rk29_adc_battery_get_charge_level(bat))
	{
		bat->bat_status = POWER_SUPPLY_STATUS_CHARGING;
		if (pdata->charge_ok_pin != INVALID_GPIO)
		{
			if (gpio_get_value(pdata->charge_ok_pin) == pdata->charge_ok_level)
			{
				bat->bat_status = POWER_SUPPLY_STATUS_FULL;
				bat->bat_capacity = 100;
			}
		}
	}

#if 0
	rk29_adc_battery_poweron_capacity_check();
#else
	poweron_check = 1;
#endif

	/* Immediate power off for battery protection */
	if (bat->bat_voltageAvg <= (pdata->adc_bat_levels[BATT_ZERO_VOL_IDX] + 50))
	{
		printk("%umV -> low battery: powerdown (%u)\n", bat->bat_voltageAvg, pdata->adc_bat_levels[BATT_ZERO_VOL_IDX]+50);
		system_state = SYSTEM_POWER_OFF;
		pm_power_off();
	}
}
static int rk29_adc_battery_get_ac_property(struct power_supply *psy,
		enum power_supply_property psp,
		union power_supply_propval *val)
{
	int ret = 0;
	charger_type_t charger;
	charger = CHARGER_USB;
	switch (psp)
	{
		case POWER_SUPPLY_PROP_ONLINE:
		if (psy->type == POWER_SUPPLY_TYPE_MAINS)
		{
			if (rk29_adc_battery_get_charge_level(gBatteryData))
			{
				val->intval = 1;
			}
			else
			{
				val->intval = 0;
			}
		}
		DBG("%s:%d\n",__FUNCTION__,val->intval);
		break;

		default:
		ret = -EINVAL;
		break;
	}
	return ret;
}
static void rk29_adc_battery_capacity_samples(struct rk29_adc_battery_data *bat)
{
	int capacity = 0;

	/* First collect minimum number of samples needed for
	 * calculation of mean value
	 */
	if (bat->bat_status_cnt < NUM_VOLTAGE_SAMPLE)
	{
		gBatCapacityDisChargeCnt = 0;
		gBatCapacityChargeCnt = 0;
		return;
	}

	/* calculate capacity currently available in battery. */
	capacity = rk29_adc_battery_voltage_to_capacity(bat, bat->bat_voltageAvg);

	if (rk29_adc_battery_get_charge_level(bat))
	{
		/* This is executed if the battery is charging... */
		rk29_adc_bat_capacity_charge(bat, capacity);
	}
	else
	{
		/* Battery is discharging */
		rk29_adc_bat_capacity_discharge(bat, capacity);
	}

	/* save current capacity for comparisions in next run */
	capacitytmp = capacity;
}
static int rk29_adc_battery_voltage_to_capacity(struct rk29_adc_battery_data *bat, int BatVoltage)
{
	int i = 0;
	int capacity = 0;

	struct batt_vol_cal *p;
	p = batt_table;

	if (rk29_adc_battery_get_charge_level(bat)){  //charge
		if(BatVoltage >= (p[BATT_NUM - 1].charge_vol)){
			capacity = 100;
		}	
		else{
			if(BatVoltage <= (p[0].charge_vol)){
				capacity = 0;
			}
			else{
				for(i = 0; i < BATT_NUM - 1; i++){

					if(((p[i].charge_vol) <= BatVoltage) && (BatVoltage < (p[i+1].charge_vol))){
						capacity =  i * 10 + ((BatVoltage - p[i].charge_vol) * 10) / (p[i+1].charge_vol- p[i].charge_vol);
						break;
					}
				}
			}  
		}

	}
	else{  //discharge
		if(BatVoltage >= (p[BATT_NUM - 1].dis_charge_vol)){
			capacity = 100;
		}	
		else{
			if(BatVoltage <= (p[0].dis_charge_vol)){
				capacity = 0;
			}
			else{
				for(i = 0; i < BATT_NUM - 1; i++){
					if(((p[i].dis_charge_vol) <= BatVoltage) && (BatVoltage < (p[i+1].dis_charge_vol))){
						capacity =   i * 10 + ((BatVoltage - p[i].dis_charge_vol) * 10) / (p[i+1].dis_charge_vol- p[i].dis_charge_vol); ;
						break;
					}
				}
			}  

		}


	}
    return capacity;
}
/* Get capacity from voltage value.
 * This function uses the adc_raw_table_bat[] table to retreive
 * the capacity in 0..100% from the current battery voltage mV value.
 *
 * \param *bat pointer to battery struct.
 * \param BatWoltage Battery voltage in mV.
 * \return capacity in 0..100%
 */
static int rk29_adc_battery_voltage_to_capacity(
		struct rk29_adc_battery_data *bat, int BatVoltage)
{
	struct rk29_adc_battery_platform_data *pdata = bat->pdata;
	int i = 0;
	int capacity = 0;
	int *p = pdata->adc_raw_table_bat;

	DBG("Bat=%u ", BatVoltage);

	/* discharge table is preset, check if we're charging */
	if (rk29_adc_battery_get_charge_level(bat))
	{
		DBG("AC ");
	p = pdata->adc_raw_table_ac;
	}

	if (BatVoltage >= p[BAT_ADC_TABLE_LEN - 1])
	{
		/* if more or equal than last table entry: 100% */
		DBG("F100%%\n");
		capacity = 100;
		goto out;
	}

	if (BatVoltage <= p[0])
	{
		/* if less than first table entry: 0% */
		DBG("F0%%\n");
		capacity = 0;
		goto out;
	}

	/* calculate average between to table entries for 1% steps. */
	for (i = 0; i < BAT_ADC_TABLE_LEN - 1; i++)
	{
		if ((p[i] <= BatVoltage) && (BatVoltage < p[i + 1]))
		{
			capacity = i * 10
					+ ((BatVoltage - p[i]) * 10) / (p[i + 1] - p[i]);
			break;
		}
	}
	DBG("i=%u %u %u %u\n", i, p[i], p[i+1], capacity);

out:
	return capacity;
}
static void rk29_adc_battery_voltage_samples(struct rk29_adc_battery_data *bat)
{
	int value;
	int i,*pStart = bat->adc_samples, num = 0;
	int level = rk29_adc_battery_get_charge_level(bat);


	value = bat->adc_val;
	adc_async_read(bat->client);

	*pSamples++ = adc_to_voltage(value);

	bat->bat_status_cnt++;
	if (bat->bat_status_cnt > NUM_VOLTAGE_SAMPLE)  bat->bat_status_cnt = NUM_VOLTAGE_SAMPLE + 1;

	num = pSamples - pStart;
	
	if (num >= NUM_VOLTAGE_SAMPLE){
		pSamples = pStart;
		num = NUM_VOLTAGE_SAMPLE;

	}

	value = 0;
	for (i = 0; i < num; i++){
		value += bat->adc_samples[i];
	}
	bat->bat_voltage = value / num;

	/*消除毛刺电压*/
	if(1 == level){
		if(bat->bat_voltage >= batt_table[BATT_NUM-1].charge_vol+ 10)
			bat->bat_voltage = batt_table[BATT_NUM-1].charge_vol  + 10;
		else if(bat->bat_voltage <= batt_table[0].charge_vol  - 10)
			bat->bat_voltage =  batt_table[0].charge_vol - 10;
	}
	else{
		if(bat->bat_voltage >= batt_table[BATT_NUM-1].dis_charge_vol+ 10)
			bat->bat_voltage = batt_table[BATT_NUM-1].dis_charge_vol  + 10;
		else if(bat->bat_voltage <= batt_table[0].dis_charge_vol  - 10)
			bat->bat_voltage =  batt_table[0].dis_charge_vol - 10;

	}
}
static int rk29_adc_battery_voltage_to_capacity(struct rk29_adc_battery_data *bat, int BatVoltage)
{
    int i = 0;
	int capacity = 0;
	int *p = adc_raw_table_bat;
    
    if (rk29_adc_battery_get_charge_level(bat))
    {
        p = adc_raw_table_ac;
    }
	
	if(BatVoltage >= p[BAT_ADC_TABLE_LEN - 1])
	{
	    //当电压超过最大值
	    capacity = 100;
	}	
	else if(BatVoltage <= p[0])
	{
	    //当电压低于最小值
	    capacity = 0;
	}
	else
	{
    	//计算容量
    	for(i = 0; i < BAT_ADC_TABLE_LEN - 1; i++)
        {
    		
    		if((p[i] <= BatVoltage) && (BatVoltage < p[i+1]))
    		{
    			capacity = i * 10 + ((BatVoltage - p[i]) * 10) / (p[i+1] - p[i]);
    			break;
    		}
    	}
    }  
    return capacity;
}
static int rk29_adc_battery_status_samples(struct rk29_adc_battery_data *bat)
{
	int charge_level;
	struct rk29_adc_battery_platform_data *pdata = bat->pdata;

	/* Read supply input state */
	charge_level = rk29_adc_battery_get_charge_level(bat);

	/* If changed, control charger logic adequately */
	if (charge_level != old_charge_level)
	{
		old_charge_level = charge_level;
		bat->bat_change = 1;

		if (charge_level)
		{
			rk29_adc_battery_charge_enable(bat);
		}
		else
		{
			rk29_adc_battery_charge_disable(bat);
		}
		/* Debounce change detection */
		bat->bat_status_cnt = 0;
	}

	if (charge_level == 0)
	{
		/* Not charging */
		bat->full_times = 0;
		bat->bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
		goto out;
	}

	/* If there is no charge-full hardware pin... */
	if (pdata->charge_ok_pin == INVALID_GPIO)
	{
		/* simulate charge full detection by capacity */
		if (bat->bat_capacity == 100)
		{
			if (bat->bat_status != POWER_SUPPLY_STATUS_FULL)
			{
				bat->bat_status = POWER_SUPPLY_STATUS_FULL;
				bat->bat_change = 1;
			}
		}
		else
		{
			bat->bat_status = POWER_SUPPLY_STATUS_CHARGING;
		}
		goto out;
	}

	/* Read GPIO stating fully-charged */
	if (gpio_get_value(pdata->charge_ok_pin) != pdata->charge_ok_level)
	{
		/* Hardware logic still charging */
		bat->full_times = 0;
		bat->bat_status = POWER_SUPPLY_STATUS_CHARGING;
	}
	else
	{
		/* Hardware finished charging. */
		if (bat->full_times < NUM_CHARGE_FULL_DELAY_TIMES)
		{
			bat->full_times++;
		}

		if ((bat->full_times >= NUM_CHARGE_FULL_DELAY_TIMES)
				&& (bat->bat_status != POWER_SUPPLY_STATUS_FULL))
		{
			bat->bat_status = POWER_SUPPLY_STATUS_FULL;
			bat->bat_capacity = 100;
			bat->bat_change = 1;
		}
	}
	out: return charge_level;
}
//static int rk29_adc_battery_get_capacity_ext(int BatVoltage)
static void rk29_adc_battery_capacity_samples(struct rk29_adc_battery_data *bat)
{
	int capacity = 0;
	struct rk29_adc_battery_platform_data *pdata = bat->pdata;
	
    //充放电状态变化后,Buffer填满之前,不更新
	if (bat->bat_status_cnt < NUM_VOLTAGE_SAMPLE)  
	{
	    gBatCapacityDisChargeCnt = 0;
	    gBatCapacityChargeCnt    = 0;
	    return;
	}
	
    capacity = rk29_adc_battery_voltage_to_capacity(bat, bat->bat_voltage);
	    
    if (rk29_adc_battery_get_charge_level(bat))
    {
        if (capacity > bat->bat_capacity)
        {
            //实际采样到的电压比显示的电压大,逐级上升
            if (++gBatCapacityDisChargeCnt >= NUM_CHARGE_MIN_SAMPLE)
            {
                gBatCapacityDisChargeCnt = 0;
                if (bat->bat_capacity < 99)
                {
                    bat->bat_capacity++;
                    bat->bat_change  = 1;
                }
            }
            gBatCapacityChargeCnt = 0;
        }
        else
        {
            gBatCapacityDisChargeCnt = 0;
            gBatCapacityChargeCnt++;
            
            if (pdata->charge_ok_pin != INVALID_GPIO)
            {
                if (gpio_get_value(pdata->charge_ok_pin) == pdata->charge_ok_level)
                {
                    //检测到电池充满标志,同时长时间内充电电压无变化,开始启动计时充电,快速上升容量
                    if (gBatCapacityChargeCnt >= NUM_CHARGE_MIN_SAMPLE)
                    {
                        gBatCapacityChargeCnt = 0;
                        if (bat->bat_capacity < 99)
                        {
                            bat->bat_capacity++;
                            bat->bat_change  = 1;
                        }
                    }
                }
                else
                {
                    if (capacity > capacitytmp)
                    {
                        //过程中如果电压有增长,定时器复位,防止定时器模拟充电比实际充电快
                        gBatCapacityChargeCnt = 0;
                    }
                    if (/*(bat->bat_capacity >= 80) && */(gBatCapacityChargeCnt > NUM_CHARGE_MAX_SAMPLE))
                    {
                        gBatCapacityChargeCnt = (NUM_CHARGE_MAX_SAMPLE - NUM_CHARGE_MID_SAMPLE);
                        if (bat->bat_capacity < 99)
                        {
                            bat->bat_capacity++;
                            bat->bat_change  = 1;
                        }
                    }
                }
            }
            else
            {
                //没有充电满检测脚,长时间内电压无变化,定时器模拟充电
                if (capacity > capacitytmp)
                {
                    //过程中如果电压有增长,定时器复位,防止定时器模拟充电比实际充电快
                    gBatCapacityChargeCnt = 0;
                }
                if (gBatCapacityChargeCnt > NUM_CHARGE_MAX_SAMPLE)
                {
                    gBatCapacityChargeCnt = (NUM_CHARGE_MAX_SAMPLE - NUM_CHARGE_MID_SAMPLE);
                    if (bat->bat_capacity < 100)
                    {
                        bat->bat_capacity++;
                        bat->bat_change  = 1;
                    }
                }
            }            
        }
    }    
    else
    {   
        //放电时,只允许电压下降
        if (capacity < bat->bat_capacity)
        {
            if (++gBatCapacityDisChargeCnt >= NUM_DISCHARGE_MIN_SAMPLE)
            {
                gBatCapacityDisChargeCnt = 0;
                if (bat->bat_capacity > 0)
                {
                    bat->bat_capacity-- ;
                    bat->bat_change  = 1;
                }
            }
        }
        else
        {
            gBatCapacityDisChargeCnt = 0;
        }
        
        gBatCapacityChargeCnt = 0;
    }
	capacitytmp = capacity;
}
static int rk29_adc_battery_status_samples(struct rk29_adc_battery_data *bat)
{
    int charge_level;
    struct rk29_adc_battery_platform_data *pdata = bat->pdata;
    
    charge_level = rk29_adc_battery_get_charge_level(bat);
    
    //检测充电状态变化情况
    if (charge_level != old_charge_level)
    {
        old_charge_level = charge_level;
        bat->bat_change  = 1;
        if(charge_level) 
        {            
            rk29_adc_battery_charge_enable(bat);
        }
        else
        {
            rk29_adc_battery_charge_disable(bat);
        }
        bat->bat_status_cnt = 0;        //状态变化开始计数
    }
    
    //获取稳定的充电状态
	if(charge_level == 0)
	{   
	    //未充电
	    bat->full_times = 0;
        bat->bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
	}
	else
	{
	    //充电	    
        if (pdata->charge_ok_pin == INVALID_GPIO)
        {
            //没有charge_ok_pin,检测容量
            if (bat->bat_capacity == 100)
            {
                if (bat->bat_status != POWER_SUPPLY_STATUS_FULL)
                {
                    bat->bat_status = POWER_SUPPLY_STATUS_FULL;
                    bat->bat_change  = 1;
                }
            }
            else
            {
                bat->bat_status = POWER_SUPPLY_STATUS_CHARGING;
            }
        }
        else
        {
            //有充电检测教
            if (gpio_get_value(pdata->charge_ok_pin) != pdata->charge_ok_level)
            {
                //没有检测到充电满电平标志
                bat->full_times = 0;
                bat->bat_status = POWER_SUPPLY_STATUS_CHARGING;
            }
            else
            {
                //检测到充电满电平标志
                bat->full_times++;
                if (bat->full_times >= NUM_CHARGE_FULL_DELAY_TIMES) 
                {
                    bat->full_times = NUM_CHARGE_FULL_DELAY_TIMES + 1;
                }

                if ((bat->full_times >= NUM_CHARGE_FULL_DELAY_TIMES) && (bat->bat_capacity >= 99))
    		    {
    		        if (bat->bat_status != POWER_SUPPLY_STATUS_FULL)
                    {
                        bat->bat_status = POWER_SUPPLY_STATUS_FULL;
                        bat->bat_capacity = 100;
                        bat->bat_change  = 1;
                    }
    		    }
    		    else
    		    {
    		        bat->bat_status = POWER_SUPPLY_STATUS_CHARGING;
    		    }
            }
        }
    }
    
	return charge_level;
}