Beispiel #1
0
s32 axp81x_usb_ac_vol_limit(struct axp_charger *charger, aw_charge_type port_type, u32 vol_limit)
{
	u8 tmp = 0;

	if( (CHARGE_USB_20 == port_type) || (CHARGE_USB_30 == port_type)) {
		if(vol_limit >= 4000 && vol_limit <=4700){
			tmp = (vol_limit - 4000)/100;
			tmp = tmp << 3;
			axp_update(axp_charger->master, AXP81X_CHARGE_VBUS, tmp,0x38);
		}else
			DBG_PSY_MSG(DEBUG_CHG, "set usb limit voltage error,%d mV\n",vol_limit);
	}else if (CHARGE_AC == port_type) {
		if(vol_limit >= 4000 && vol_limit <=4700){
			tmp = (vol_limit - 4000)/100;
			tmp = tmp << 3;
#ifdef BPI-M3
			axp_update(axp_charger->master, AXP81X_CHARGE_AC, tmp,0x38);
#else
printk("BPI-M3: tmp [%02X]\n",tmp);
printk("BPI-M3: set PMIC AC 4000mA\n");
			axp_update(axp_charger->master, AXP81X_CHARGE_AC, 0x85,0x38);
#endif
		}else
			DBG_PSY_MSG(DEBUG_CHG, "set ac limit voltage error,%d mV\n",vol_limit);
	}
	return 0;
}
static void axp_lateresume(struct early_suspend *h)
{
	uint8_t tmp;
	int value;

	value = axp_powerkey_get();
	if (0 != value)
		axp_powerkey_set(0);

	DBG_PSY_MSG(DEBUG_SPLY, "======late resume=======\n");
#if defined (CONFIG_AXP_CHGCHANGE)
	early_suspend_flag = 0;
	if(axp81x_config.pmu_runtime_chgcur == 0)
		axp_clr_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	else
		axp_set_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	if(axp81x_config.pmu_runtime_chgcur >= 300000 && axp81x_config.pmu_runtime_chgcur <= 2550000){
		tmp = (axp81x_config.pmu_runtime_chgcur -200001)/150000;
		axp_update(axp_charger->master, AXP81X_CHARGE_CONTROL1, tmp,0x0F);
	}else if(axp81x_config.pmu_runtime_chgcur < 300000){
		axp_clr_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}else{
		axp_set_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}
#endif
}
Beispiel #3
0
/* 得到开路电压 */
static int axp_get_ocv(void)
{
	int battery_ocv;
	uint8_t v[2];
	axp_reads(AXP_OCV_BUFFER0, 2, v);
	battery_ocv = ((v[0] << 4) + (v[1] & 0x0f)) * 11 /10;
	DBG_PSY_MSG("battery_ocv = %d\n", battery_ocv);
	return battery_ocv;
}
Beispiel #4
0
static void axp_set_basecap(int base_cap)
{
	uint8_t val;
	if(base_cap >= 0)
		val = base_cap & 0x7F;
	else
		val = ABS(base_cap) | 0x80;
	DBG_PSY_MSG("axp_set_basecap = %d\n", val);
	axp_write(POWER20_DATA_BUFFER4, val);
}
Beispiel #5
0
void axp_usbac_out(struct axp_charger *charger)
{
	if (!axp_config->pmu_init_bc_en) {
		DBG_PSY_MSG(DEBUG_CHG, "axp22 ac/usb out!\n");
		if(timer_pending(&charger->usb_status_timer))
			del_timer_sync(&charger->usb_status_timer);
		/* if we plugged usb & ac at the same time,then unpluged ac quickly while the usb driver */
		/* do not finished detecting,the charger type is error!So delay the charger type report 2s */
		mod_timer(&charger->usb_status_timer,jiffies + msecs_to_jiffies(2000));
	}
	axp_usb_ac_check_status(charger);
}
Beispiel #6
0
static void axp_usb_ac_check_status(struct axp_charger *charger)
{
	if (!axp_config->pmu_init_bc_en) {
		charger->usb_valid = (((CHARGE_USB_20 == axp_usbcurflag) || (CHARGE_USB_30 == axp_usbcurflag)) &&
					charger->ext_valid);
		charger->usb_adapter_valid = ((0 == charger->ac_valid) && (CHARGE_USB_20 != axp_usbcurflag) &&
						(CHARGE_USB_30 != axp_usbcurflag) && (charger->ext_valid));
		if(charger->in_short) {
			charger->ac_valid = ((charger->usb_adapter_valid == 0) && (charger->usb_valid == 0) &&
						(charger->ext_valid));
		}
	} else {
		charger->usb_adapter_valid = 0;
	}
	power_supply_changed(&charger->ac);
	power_supply_changed(&charger->usb);

	DBG_PSY_MSG(DEBUG_CHG, "usb_valid=%d ac_valid=%d usb_adapter_valid=%d\n",charger->usb_valid,
				charger->ac_valid, charger->usb_adapter_valid);
	DBG_PSY_MSG(DEBUG_CHG, "usb_det=%d ac_det=%d \n",charger->usb_det,
				charger->ac_det);
}
Beispiel #7
0
void axp_usbac_in(struct axp_charger *charger)
{
	u32 var;
	u8 tmp;

	if (!axp_config->pmu_init_bc_en) {
		DBG_PSY_MSG(DEBUG_CHG, "axp ac/usb in!\n");
		if(timer_pending(&charger->usb_status_timer))
			del_timer_sync(&charger->usb_status_timer);
		/* must limit the current now,and will again fix it while usb/ac detect finished! */
		if(axp_config->pmu_usbcur_pc){
			var = axp_config->pmu_usbcur_pc;
			if(var < 500) {
				tmp = 0x00;   /* 100mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			} else if (var < 900) {
				tmp = 0x10;   /* 500mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			} else if (var < 1500) {
				tmp = 0x20;   /* 900mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			} else if (var < 2000) {
				tmp = 0x30;   /* 1500mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			} else if (var < 2500) {
				tmp = 0x40;   /* 2000mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			} else if (var < 3000) {
				tmp = 0x50;   /* 2500mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			} else if (var < 3500) {
				tmp = 0x60;   /* 3000mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			} else if (var < 4000) {
				tmp = 0x70;   /* 3500mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			} else {
				tmp = 0x80;   /* 4000mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			}
		} else {
			tmp = 0x10;   /* 500mA */
			axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
		}
		/* this is about 3.5s,while the flag set in usb drivers after usb plugged */
		mod_timer(&charger->usb_status_timer,jiffies + msecs_to_jiffies(5000));
	}
	axp_usb_ac_check_status(charger);
}
Beispiel #8
0
static int axp_get_coulomb(void)
{
	uint8_t  temp[8];
	uint64_t  rValue1,rValue2,rValue;
	uint32_t Cur_CoulombCounter_tmp,m;

	axp_reads(POWER20_BAT_CHGCOULOMB3,8, temp);
	rValue1 = ((temp[0] << 24) + (temp[1] << 16) + (temp[2] << 8) + temp[3]);
	rValue2 = ((temp[4] << 24) + (temp[5] << 16) + (temp[6] << 8) + temp[7]);

	DBG_PSY_MSG("%s->%d -     CHARGINGOULB:[0]=0x%x,[1]=0x%x,[2]=0x%x,[3]=0x%x\n",__FUNCTION__,__LINE__,temp[0],temp[1],temp[2],temp[3]);
	DBG_PSY_MSG("%s->%d - DISCHARGINGCLOUB:[4]=0x%x,[5]=0x%x,[6]=0x%x,[7]=0x%x\n",__FUNCTION__,__LINE__,temp[4],temp[5],temp[6],temp[7]);

	rValue = (ABS(rValue1 - rValue2)) * 4369;
	m = axp_get_freq() * 480;
	do_div(rValue,m);
	if(rValue1 >= rValue2)
		Cur_CoulombCounter_tmp = (int)rValue;
	else
		Cur_CoulombCounter_tmp = (int)(0 - rValue);
	
	DBG_PSY_MSG("Cur_CoulombCounter_tmp = %d\n",Cur_CoulombCounter_tmp);
	return Cur_CoulombCounter_tmp;	//unit mAh
}
static void axp_earlysuspend(struct early_suspend *h)
{
	uint8_t tmp;

	DBG_PSY_MSG(DEBUG_SPLY, "======early suspend=======\n");

#if defined (CONFIG_AXP_CHGCHANGE)
	early_suspend_flag = 1;
	if(axp81x_config.pmu_earlysuspend_chgcur == 0)
		axp_clr_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	else
		axp_set_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	if(axp81x_config.pmu_earlysuspend_chgcur >= 300000 && axp81x_config.pmu_earlysuspend_chgcur <= 2550000){
		tmp = (axp81x_config.pmu_earlysuspend_chgcur -200001)/150000;
		axp_update(axp_charger->master, AXP81X_CHARGE_CONTROL1, tmp,0x0F);
	}
#endif
}
Beispiel #10
0
int axp81x_chg_current_limit(int current_limit)
{
	uint8_t tmp = 0;
#if defined (CONFIG_AXP_CHGCHANGE)
	if(current_limit == 0)
		axp_clr_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	else
		axp_set_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	DBG_PSY_MSG(DEBUG_SPLY, "current_limit = %d\n", current_limit);
	if(current_limit >= AXP81X_CHARGE_CURRENT_MIN && current_limit <= AXP81X_CHARGE_CURRENT_MAX){
		tmp = (current_limit -AXP81X_CHARGE_CURRENT_STEP)/AXP81X_CHARGE_CURRENT_STEP;
		spin_lock(&axp_charger->charger_lock);
		axp_charger->chgcur = tmp *AXP81X_CHARGE_CURRENT_STEP + AXP81X_CHARGE_CURRENT_MIN;
		spin_unlock(&axp_charger->charger_lock);
		axp_update(axp_charger->master, AXP81X_CHARGE_CONTROL1, tmp,0x0F);
	}else if(current_limit < AXP81X_CHARGE_CURRENT_MIN){
		axp_clr_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}else{
		axp_set_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}
#endif
	return 0;
}
Beispiel #11
0
static void axp_usb(struct work_struct *work)
{
	int var;
	uint8_t tmp,val;

	DBG_PSY_MSG(DEBUG_CHG, "[axp_usb]axp_usbcurflag = %d\n",axp_usbcurflag);

	axp_read(axp_charger->master, AXP_CHARGE_STATUS, &val);
	if ((val & 0x02)) { /* usb and ac in short*/
		if((val & 0x10) == 0x00){/*usb or usb adapter can not be used*/
			DBG_PSY_MSG(DEBUG_CHG, "USB not insert!\n");
			tmp = 0x10;
			axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
		}else if(CHARGE_USB_20 == axp_usbcurflag){
			DBG_PSY_MSG(DEBUG_CHG, "set usbcur_pc %d mA\n",axp_config->pmu_usbcur_pc);
			if(axp_config->pmu_usbcur_pc){
				var = axp_config->pmu_usbcur_pc;
				if(var < 500) {
					tmp = 0x00;   /* 100mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 900) {
					tmp = 0x10;   /* 500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 1500) {
					tmp = 0x20;   /* 900mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 2000) {
					tmp = 0x30;   /* 1500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 2500) {
					tmp = 0x40;   /* 2000mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 3000) {
					tmp = 0x50;   /* 2500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 3500) {
					tmp = 0x60;   /* 3000mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 3500) {
					tmp = 0x70;   /* 3500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else {
					tmp = 0x80;   /* 4000mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				}
			} else {
				tmp = 0x10;   /* 500mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			}
		}else if (CHARGE_USB_30 == axp_usbcurflag){
			tmp = 0x20; /* 900mA */
			axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
		}else {
			DBG_PSY_MSG(DEBUG_CHG, "set usbcur %d mA\n",axp_config->pmu_usbcur);
			if((axp_config->pmu_usbcur) && (axp_config->pmu_usbcur_limit)){
				var = axp_config->pmu_usbcur;
				if(var < 500) {
					tmp = 0x00;   /* 100mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 900) {
					tmp = 0x10;   /* 500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 1500) {
					tmp = 0x20;   /* 900mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 2000) {
					tmp = 0x30;   /* 1500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 2500) {
					tmp = 0x40;   /* 2000mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 3000) {
					tmp = 0x50;   /* 2500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 3500) {
					tmp = 0x60;   /* 3000mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 4000) {
					tmp = 0x70;   /* 3500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else {
					tmp = 0x80;   /* 4000mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				}
			} else {
				tmp = 0x50;   /* 2500mA */
				DBG_PSY_MSG(DEBUG_CHG, "%s: %d,set usbcur 2500 mA\n",__func__, __LINE__);
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			}
		}

		if(!vbus_curr_limit_debug){ //usb current not limit
			DBG_PSY_MSG(DEBUG_CHG, "vbus_curr_limit_debug = %d\n",vbus_curr_limit_debug);
			tmp = 0x50;   /* 2500mA */
			axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
		}

		if(CHARGE_USB_20 == axp_usbvolflag){
			DBG_PSY_MSG(DEBUG_CHG, "set usbvol_pc %d mV\n",axp_config->pmu_usbvol_pc);
			if(axp_config->pmu_usbvol_pc){
				var = axp_config->pmu_usbvol_pc * 1000;
				if(var >= 4000000 && var <=4700000){
					tmp = (var - 4000000)/100000;
					val = tmp << 3;
					axp_update(axp_charger->master, AXP_CHARGE_VBUS, val,0x38);
				}else
					DBG_PSY_MSG(DEBUG_CHG, "set usb limit voltage error,%d mV\n",axp_config->pmu_usbvol_pc);
			}
		}else if(CHARGE_USB_30 == axp_usbvolflag) {
			val = 7 << 3;
			axp_update(axp_charger->master, AXP_CHARGE_VBUS, val,0x38);
		}else {
			DBG_PSY_MSG(DEBUG_CHG, "set usbvol %d mV\n",axp_config->pmu_usbvol);
			if((axp_config->pmu_usbvol) && (axp_config->pmu_usbvol_limit)){
				var = axp_config->pmu_usbvol * 1000;
				if(var >= 4000000 && var <=4700000){
					tmp = (var - 4000000)/100000;
					val = tmp << 3;
					axp_update(axp_charger->master, AXP_CHARGE_VBUS, val,0x38);
				}else
					DBG_PSY_MSG(DEBUG_CHG, "set usb limit voltage error,%d mV\n",axp_config->pmu_usbvol);
			}
		}
	}else {
		if((val & 0x50) == 0x00){/*usb and ac can not be used*/
			DBG_PSY_MSG(DEBUG_CHG, "USB not insert!\n");
			tmp = 0x10; /* 500mA */
			axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			tmp = 0x0; /* 1500mA */
			axp_update(axp_charger->master, AXP_CHARGE_AC, tmp,0x07);
		}else if(CHARGE_USB_20 == axp_usbcurflag){
			DBG_PSY_MSG(DEBUG_CHG, "set usbcur_pc %d mA\n",axp_config->pmu_usbcur_pc);
			if(axp_config->pmu_usbcur_pc){
				var = axp_config->pmu_usbcur_pc;
				if(var < 500) {
					tmp = 0x00;   /* 100mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 900) {
					tmp = 0x10;   /* 500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 1500) {
					tmp = 0x20;   /* 900mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 2000) {
					tmp = 0x30;   /* 1500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 2500) {
					tmp = 0x40;   /* 2000mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 3000) {
					tmp = 0x50;   /* 2500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 3500) {
					tmp = 0x60;   /* 3000mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else if (var < 4000) {
					tmp = 0x70;   /* 3500mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				} else {
					tmp = 0x80;   /* 4000mA */
					axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
				}
			} else {
				tmp = 0x10;   /* 500mA */
				axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
			}
		}else if (CHARGE_USB_30 == axp_usbcurflag){
			tmp = 0x20; /* 900mA */
			axp_update(axp_charger->master, AXP_CHARGE_CONTROL3, tmp,0xf0);
		}else {
			DBG_PSY_MSG(DEBUG_CHG, "set usbcur %d mA\n",axp_config->pmu_usbcur);
			if((axp_config->pmu_usbcur) && (axp_config->pmu_usbcur_limit)){
				var = axp_config->pmu_usbcur;
				if (var < 2000) {
					tmp = 0x01;   /* 1500mA */
					axp_update(axp_charger->master, AXP_CHARGE_AC, tmp,0x07);
				} else if (var < 2500) {
					tmp = 0x02;   /* 2000mA */
					axp_update(axp_charger->master, AXP_CHARGE_AC, tmp,0x07);
				} else if (var < 3000) {
					tmp = 0x03;   /* 2500mA */
					axp_update(axp_charger->master, AXP_CHARGE_AC, tmp,0x07);
				} else if (var < 3500) {
					tmp = 0x04;   /* 3000mA */
					axp_update(axp_charger->master, AXP_CHARGE_AC, tmp,0x07);
				} else if (var < 3500) {
					tmp = 0x05;   /* 3500mA */
					axp_update(axp_charger->master, AXP_CHARGE_AC, tmp,0x07);
				} else {
					tmp = 0x06;   /* 4000mA */
					axp_update(axp_charger->master, AXP_CHARGE_AC, tmp,0x07);
				}
			} else {
				tmp = 0x05;   /* 4000mA */
				axp_update(axp_charger->master, AXP_CHARGE_AC, tmp,0x07);
			}
		}

		if(!vbus_curr_limit_debug){ //usb current not limit
			DBG_PSY_MSG(DEBUG_CHG, "vbus_curr_limit_debug = %d\n",vbus_curr_limit_debug);
			tmp = 0x03;   /* 2500mA */
			axp_update(axp_charger->master, AXP_CHARGE_AC, tmp,0xf0);
		}

		if(CHARGE_USB_20 == axp_usbvolflag){
			DBG_PSY_MSG(DEBUG_CHG, "set usbvol_pc %d mV\n",axp_config->pmu_usbvol_pc);
			if(axp_config->pmu_usbvol_pc){
				var = axp_config->pmu_usbvol_pc * 1000;
				if(var >= 4000000 && var <=4700000){
					tmp = (var - 4000000)/100000;
					val = tmp << 3;
					axp_update(axp_charger->master, AXP_CHARGE_VBUS, val,0x38);
				}else
					DBG_PSY_MSG(DEBUG_CHG, "set usb limit voltage error,%d mV\n",axp_config->pmu_usbvol_pc);
			}
		}else if(CHARGE_USB_30 == axp_usbvolflag) {
			val |= 7 << 3;
			axp_update(axp_charger->master, AXP_CHARGE_VBUS, val,0x38);
		}else {
			DBG_PSY_MSG(DEBUG_CHG, "set usbvol %d mV\n",axp_config->pmu_usbvol);
			if((axp_config->pmu_usbvol) && (axp_config->pmu_usbvol_limit)){
				var = axp_config->pmu_usbvol * 1000;
				if(var >= 4000000 && var <=4700000){
					tmp = (var - 4000000)/100000;
					val = tmp << 3;
					axp_update(axp_charger->master, AXP_CHARGE_AC, val,0x38);
				}else
					DBG_PSY_MSG(DEBUG_CHG, "set usb limit voltage error,%d mV\n",axp_config->pmu_usbvol);
			}
		}
	}
}
Beispiel #12
0
static void axp_usb(struct work_struct *work)
{
	int var;
	uint8_t tmp,val;

	DBG_PSY_MSG(DEBUG_CHG, "[axp_usb]axp_usbcurflag = %d\n",axp_usbcurflag);

	axp_read(axp_charger->master, AXP_CHARGE_STATUS, &val);
	if((val & 0x10) == 0x00){/*usb or usb adapter can not be used*/
		DBG_PSY_MSG(DEBUG_CHG, "USB not insert!\n");
		axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x02);
		axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x01);
	}else if(CHARGE_USB_20 == axp_usbcurflag){
		DBG_PSY_MSG(DEBUG_CHG, "set usbcur_pc %d mA\n",axp_config->pmu_usbcur_pc);
		if(axp_config->pmu_usbcur_pc){
			var = axp_config->pmu_usbcur_pc * 1000;
			if(var >= 900000)
				axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
			else if (var < 900000){
				axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x02);
				axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x01);
			}
		}else//not limit
			axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
	}else if (CHARGE_USB_30 == axp_usbcurflag){
		axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
	}else {
		DBG_PSY_MSG(DEBUG_CHG, "set usbcur %d mA\n",axp_config->pmu_usbcur);
		if((axp_config->pmu_usbcur) && (axp_config->pmu_usbcur_limit)){
			var = axp_config->pmu_usbcur * 1000;
			if(var >= 900000)
				axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
			else if (var < 900000){
				axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x02);
				axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x01);
			}
		}else //not limit
			axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
	}

	if(!vbus_curr_limit_debug){ //usb current not limit
		DBG_PSY_MSG(DEBUG_CHG, "vbus_curr_limit_debug = %d\n",vbus_curr_limit_debug);
		axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
	}

	if(CHARGE_USB_20 == axp_usbvolflag){
		DBG_PSY_MSG(DEBUG_CHG, "set usbvol_pc %d mV\n",axp_config->pmu_usbvol_pc);
		if(axp_config->pmu_usbvol_pc){
			axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x40);
			var = axp_config->pmu_usbvol_pc * 1000;
			if(var >= 4000000 && var <=4700000){
				tmp = (var - 4000000)/100000;
				axp_read(axp_charger->master, AXP_CHARGE_VBUS,&val);
				val &= 0xC7;
				val |= tmp << 3;
				axp_write(axp_charger->master, AXP_CHARGE_VBUS,val);
			}else
				DBG_PSY_MSG(DEBUG_CHG, "set usb limit voltage error,%d mV\n",axp_config->pmu_usbvol_pc);
		}else
		    axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x40);
	}else if(CHARGE_USB_30 == axp_usbvolflag) {
		axp_read(axp_charger->master, AXP_CHARGE_VBUS,&val);
		val &= 0xC7;
		val |= 7 << 3;
		axp_write(axp_charger->master, AXP_CHARGE_VBUS,val);
	}else {
		DBG_PSY_MSG(DEBUG_CHG, "set usbvol %d mV\n",axp_config->pmu_usbvol);
		if((axp_config->pmu_usbvol) && (axp_config->pmu_usbvol_limit)){
			axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x40);
			var = axp_config->pmu_usbvol * 1000;
			if(var >= 4000000 && var <=4700000){
				tmp = (var - 4000000)/100000;
				axp_read(axp_charger->master, AXP_CHARGE_VBUS,&val);
				val &= 0xC7;
				val |= tmp << 3;
				axp_write(axp_charger->master, AXP_CHARGE_VBUS,val);
			}else
				DBG_PSY_MSG(DEBUG_CHG, "set usb limit voltage error,%d mV\n",axp_config->pmu_usbvol);
		}else
		    axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x40);
	}
}
static void axp_charging_monitor(struct work_struct *work)
{
	struct axp_charger *charger;
	uint8_t	val,temp_val[4];
	int	pre_rest_vol,pre_bat_curr_dir;
	unsigned long power_sply = 0;

	charger = container_of(work, struct axp_charger, work.work);
	pre_rest_vol = charger->rest_vol;
	pre_bat_curr_dir = charger->bat_current_direction;
	axp_charger_update_state(charger);
	axp_charger_update(charger, &axp81x_config);
	axp_read(charger->master, AXP81X_CAP,&val);

	spin_lock(&charger->charger_lock);
	charger->rest_vol	= (int)	(val & 0x7F);
	spin_unlock(&charger->charger_lock);

	if (axp_debug & DEBUG_SPLY) {
		DBG_PSY_MSG(DEBUG_SPLY, "charger->ic_temp = %d\n",charger->ic_temp);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->bat_temp = %d\n",charger->bat_temp);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->vbat = %d\n",charger->vbat);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->ibat = %d\n",charger->ibat);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->ocv = %d\n",charger->ocv);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->disvbat = %d\n",charger->disvbat);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->disibat = %d\n",charger->disibat);
		power_sply = charger->disvbat * charger->disibat;
		if (0 != power_sply)
			power_sply = power_sply/1000;
		DBG_PSY_MSG(DEBUG_SPLY, "power_sply = %ld mW\n",power_sply);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->rest_vol = %d\n",charger->rest_vol);
		axp_reads(charger->master,0xba,2,temp_val);
		DBG_PSY_MSG(DEBUG_SPLY, "Axp Rdc = %d\n",(((temp_val[0] & 0x1f) <<8) + temp_val[1])*10742/10000);
		axp_reads(charger->master,0xe0,2,temp_val);
		DBG_PSY_MSG(DEBUG_SPLY, "Axp batt_max_cap = %d\n",(((temp_val[0] & 0x7f) <<8) + temp_val[1])*1456/1000);
		axp_reads(charger->master,0xe2,2,temp_val);
		DBG_PSY_MSG(DEBUG_SPLY, "Axp coulumb_counter = %d\n",(((temp_val[0] & 0x7f) <<8) + temp_val[1])*1456/1000);
		axp_read(charger->master,0xb8,temp_val);
		DBG_PSY_MSG(DEBUG_SPLY, "Axp REG_B8 = %x\n",temp_val[0]);
		axp_reads(charger->master,0xe4,2,temp_val);
		DBG_PSY_MSG(DEBUG_SPLY, "Axp OCV_percentage = %d\n",(temp_val[0] & 0x7f));
		DBG_PSY_MSG(DEBUG_SPLY, "Axp Coulumb_percentage = %d\n",(temp_val[1] & 0x7f));
		DBG_PSY_MSG(DEBUG_SPLY, "charger->is_on = %d\n",charger->is_on);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->bat_current_direction = %d\n",charger->bat_current_direction);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->charge_on = %d\n",charger->charge_on);
		DBG_PSY_MSG(DEBUG_SPLY, "charger->ext_valid = %d\n",charger->ext_valid);
		DBG_PSY_MSG(DEBUG_SPLY, "pmu_runtime_chgcur           = %d\n",axp81x_config.pmu_runtime_chgcur);
		DBG_PSY_MSG(DEBUG_SPLY, "pmu_earlysuspend_chgcur   = %d\n",axp81x_config.pmu_earlysuspend_chgcur);
		DBG_PSY_MSG(DEBUG_SPLY, "pmu_suspend_chgcur        = %d\n",axp81x_config.pmu_suspend_chgcur);
		DBG_PSY_MSG(DEBUG_SPLY, "pmu_shutdown_chgcur       = %d\n\n\n",axp81x_config.pmu_shutdown_chgcur);
	}

	/* if battery volume changed, inform uevent */
	if((charger->rest_vol - pre_rest_vol) || (charger->bat_current_direction != pre_bat_curr_dir)){	
		axp_reads(charger->master,0xe2,2,temp_val);
		axp_reads(charger->master,0xe4,2,(temp_val+2));
		DBG_PSY_MSG(DEBUG_SPLY, "battery vol change: %d->%d \n", pre_rest_vol, charger->rest_vol);
		DBG_PSY_MSG(DEBUG_SPLY, "for test %d %d %d %d %d %d\n",charger->vbat,charger->ocv,charger->ibat,
			(temp_val[2] & 0x7f),(temp_val[3] & 0x7f),(((temp_val[0] & 0x7f) <<8) + temp_val[1])*1456/1000);
		pre_rest_vol = charger->rest_vol;
		power_supply_changed(&charger->batt);
	}
	/* reschedule for the next time */
	schedule_delayed_work(&charger->work, charger->interval);
}